Prolog Query - Trying to understand how this resul

2019-07-17 16:47发布

问题:

So I'm trying to figure out some stuff from Prolog, but I'm not sure WHY I'm getting the result that I'm getting. Given this definition:

families(_, Smith, lucy, _, jeff, Smith).

and this query:

?- families(Ford, nancy, Ford, jeff, Smith, White).

Why is this the result?:

Ford = lucy,
Smith = jeff,
White = nancy.

Thank you!

回答1:

(A note: no need to leave spaces after the opening and before the closing parenthesis. Also, if this is homework, you should say so.)

The definition of families/6,

families(_, Smith, lucy, _, jeff, Smith).

says:

  1. Ignore first argument and fourth argument (the underscores);
  2. Unify the second and the last argument (both arguments referred to by the same variable name, Smith);
  3. Unify the third argument with the atom lucy;
  4. Unify the fifth argument with the atom jeff.

Now your query,

?- families(Ford, nancy, Ford, jeff, Smith, White).

asks:

  • Can you unify the first and third argument with the same variable, Ford?
    • yes, you can, and now Ford = lucy (from 3. in the definition).
  • Can the second argument be the atom nancy?
    • yes, and White = nancy (from 2. in the definition)
  • Can the fourth argument be the atom jeff?
    • yes, but this doesn't have any effect (from 1. in the definition)
  • Can you unify the fifth argument with the variable Smith?
    • yes, and Smith = jeff (from 4. in the definition).

This should be clear now, assuming you know how unification works. Important is that variable names in the definition and the query are in different contexts and having the same name means nothing (as in Smith in positions 2 and 6 in the definition and Smith in position 5 in the query).

Altogether this is a convoluted example that uses variable and atom names in an attempt to confuse the human reader. It forces you to pay attention though and can be useful as an example of bad programming style.



回答2:

As a visual aid to the answer by Boris, we can write the predicate and the query one beside the other,

   families( _   , Smith, lucy, _   , jeff , Smith).
?- families( Ford, nancy, Ford, jeff, Smith, White).

Now, Smith in the definition and Smith in the query are not the same! Each predicate has its own "namespace" in effect, because predicate's variables are renamed on predicate's use. So we actually have here

   families( _   , A    , lucy, _   , jeff , A    ).
?- families( Ford, nancy, Ford, jeff, Smith, White).

which matches, producing the substitution

_=Ford, A=nancy, lucy=Ford, _=jeff, jeff=Smith, A=White.

i.e.

Ford=lucy, Smith=jeff, White=nancy.

The last one is the consequence of White=A and A=nancy. A itself isn't reported because it is not one of the query's logical variables.



标签: prolog