4

I am having trouble trying to figure out in what order unification is done. I have the following query:

[X, like | Z] = [I, Y, Prolog, language].

This gives me the following result:

X = I,
Z = [Prolog, language],
Y = like.

However, what I was expecting is:

X = I,
Y = like,
Z = [Prolog, language].

Is there any specific order in which Prolog unifies terms?

EDIT: I have a feeling that Prolog is giving higher priority to unification of an atom with a variable over that of a variable with an atom. Is that so?

false
  • 10,264
  • 13
  • 101
  • 209
Priyanshul Govil
  • 518
  • 5
  • 20

2 Answers2

3

There is no order. Here is the mapping that is performed:

[I,  Y   , Prolog, language].
 |   |     +--------------+
 |   |           |
[X, like |       Z] 

if that mapping is possible (i.e. if the variables I ,Y, X, Z are bound to terms that allow unification to succeed)

In this case, assuming that all variables are unbound, then:

  • Variables I and X will become "the same variable" (more clearly, the variable name I and X will designate the same empty storage cell)

  • Variable Y will become the atom like' (more clearly, the storage cell designated by variable name Ywill be set tolike`)

  • Variable Z takes up the "rest (or suffix) of the list" (everything behind the |) and will become the complex term `[Prolog, language]'.

  • Variable Prolog is not changed and stays what it was.

David Tonhofer
  • 14,559
  • 5
  • 55
  • 51
  • Why does Prolog then output `Y = like` at the end? If I change the query to `[X, Y | Z] = [I, like, Prolog, language].` it outputs them in the order `X = I, Y = like, Z = [Prolog, language].` – Priyanshul Govil Jan 24 '21 at 17:36
  • 1
    @PriyanshulGovil Ah, that's just an irrelevant specificity of how the "toplevel" prints the result. All the conjuncts that are printed are valid at output time, there is no _meaningful_ order. – David Tonhofer Jan 24 '21 at 17:40
  • I'm still a bit puzzled. `[a, B] = [H, T].` will give me `B = T, H = a.` whereas `[a, b] = [H, T].` will give me `H = a, T = b.`. Is there no way I can find out what's happening under the hood? – Priyanshul Govil Jan 24 '21 at 17:46
  • @PriyanshulGovil Not really ... the list of `A = B` do not represent a _sequence of replacements_. They are the result of trying to find a _consistent mapping_. You can write them any way you want. – David Tonhofer Jan 24 '21 at 17:46
  • Yes, but can I not find out how Prolog is going about finding that consistent mapping? There surely must be a sequence of steps that Prolog follows. – Priyanshul Govil Jan 24 '21 at 17:48
  • So what you're saying is that it is not mentioned in the language's documentation and is based on the specific Prolog interpreter. Did I understand that correctly? – Priyanshul Govil Jan 24 '21 at 17:50
  • @PriyanshulGovil Oh yes. It's pretty involved though. Here is a paper with some pseudocode: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.329.1809 There is also a Wikipedia page on Unification: https://en.wikipedia.org/wiki/Unification_(computer_science) – David Tonhofer Jan 24 '21 at 17:51
  • @PriyanshulGovil The unification algorithm can change (some are more efficient than others) but what it should do is clear (so the result will be the same). However, printing the result is left open to the implementor. – David Tonhofer Jan 24 '21 at 17:52
  • Oh alright, it makes sense now. I'll give that paper a read. Thanks. – Priyanshul Govil Jan 24 '21 at 17:53
2

The Prolog top-level is free to order the answer substitution however it likes. And the order of the answer substitution doesn't tell you in which order the unification is done. You might get an insight into the unification order by using freeze/2:

Welcome to SWI-Prolog (threaded, 64 bits, version 8.3.17)

?- freeze(X, (write('X='), write(X), nl)), 
    freeze(Y, (write('Y='), write(Y), nl)),
    [X|Y] = [foo|bar].
X=foo
Y=bar
X = foo,
Y = bar.

?- freeze(Y, (write('Y='), write(Y), nl)),
    freeze(X, (write('X='), write(X), nl)),
    [X|Y] = [foo|bar].
X=foo
Y=bar
Y = bar,
X = foo.

At least you see that the freeze coroutines are sheduled after unification pattern and not after the way they were introduced, as does the top-level. Mostlikely in SWI-Prolog the freeze/2 result tells you the order how unification is performed.

But to the best of my knowledge the ISO core standard doesn't require a particular order. In this respect other Prolog systems might might have other preferences than SWI-Prolog. But I owe you a reference that supports this claim.