member(X,[X|_]). member(X,[_|T]) :- member(X,T).
Goal
member(mary, [john, mary, pat]).
X can't be both mary and
johnX = mary, _ = john, T = [mary, pat]member(mary, [mary, pat])
X = mary, _ = pattrue.member(X,[_|T]) and member(mary, [john,
mary, pat])X = mary, _ = john, T = [mary, pat]| Equation | Action |
| f(s1, ..., sn) = f(t1, ..., tn) | Replace with s1 = t1, ..., sn = tn |
| f(s1, ..., sn) = g(t1, ..., tn) where f ≠ g | Halt with failure |
| X = X | Delete the equation |
| t = X where t is not a variable | Replace with X = t |
| X = t where X does not occur in t and it occurs elsewhere | Apply the substitution X = t to all other terms |
| X = t where X occurs in t (but t ≠ X) | Halt with failure |
member(X,[_|T])= member(mary, [john, mary,
pat])[ | ] as consmember(X, cons(Z, T))= member(mary,
cons(john, cons(mary, cons(pat, nil))))X = marycons(Z, T) = cons(john, cons(mary, cons(pat,
nil)))X = maryZ= johnT = cons(mary, cons(pat, nil))parent(james1, charles1). parent(james1, elizabeth). parent(charles1, charles2). parent(charles1, catherine). parent(charles1, james2). grandparent(X, Y) :- parent(X, Z), parent(Z, Y).
Query: grandparent(james1, G)
X = james1, Y =
Gparent(james1, Z) parent(Z, G)
Z =
charles1parent(charles1, G)
parent(Z, Y) / X = james1, Y = G, Z = charles1
parent(charles1, G)parent(james1, charles1). parent(james1, elizabeth). parent(charles1, charles2). parent(charles1, catherine). parent(charles1, james2).
charles1
≠ james1)G = charles2G = catherineancestor(X, Z) :- parent(X, Y), ancestor(Y, Z). ancestor(X, Y) :- parent(X, Y).
Query: ancestor(james1, X)
ancestor(james1, X) with ancestor(X,
Z)Xancestor(james1, X) and
ancestor(X1, Z)X1 = james1, X = Zparent(X1, Y) / X1 = james1, X = Z ancestor(Y, Z) / X1 = james1, X = Z
Y = charles1ancestor(Y, Z). Unify with ancestor(X,
Z). ancestor(X2, Z1)> >= < =< =:= =\=
= is unification, not “evaluate and assign”. The
query X = 3 + 4. (or 3 + 4 = X.) yields X =
3 + 4. How helpful!is operator to force arithmetic evaluation.
X is 3 + 4. X = 7
is can contain variables, but they must
already be bound to numbers7 = 3 + X. false
factorial(N, F) means F
equals N!
factorial(0, 1). factorial(N, F) :- N > 0, N1 is N - 1, factorial(N1, F1), F is N * F1.
factorial(N - 1, F1) would not work. (See the
lab).
member(X, cons(john, cons(mary, nil))) member(X17, cons(X17, T))
Compute a unifying substitution (by hand). What is it?
member(X, cons(john, cons(mary, nil)))
and the clause
member(X, cons(X, T)) :- member(X,T).
Compute a unifying substitution of the goal and the head of the clause after renaming variables in the clause. What is it?
Save this Prolog.scala file. In a shell window, type
scala -i Prolog.scala
When you get a prompt, type these commands:
import Prolog._
val member = new Predicate
member('X, 'X::'Xs)!
member('X, 'Y::'Ys) :- member('X, 'Ys)
member('X, 'john :: 'mary :: 'nil)?
more
more
As you can see, the implementor of this interpreter cleverly overloaded
operators ! (fact), :- (provided that) and
? (query).
Note the single quote that is used for variables.
Now type
showMatches = true
member('X, 'john :: 'mary :: 'nil)?
more
more
What output do you get?
Now comes the hard part: Put together a complete trace of what the interpreter does. In each step, you can choose from
Use the same substitution that the Scala interpreter uses. When I ran it, the trace output started with
unify 'X with 'john = true unify 'X16 with 'john = true unify 'Xs17 with 'mary :: 'nil = true
My solution would be
Step 1. Push member(X, cons(john, cons(mary, nil))) on goal
stack
Step 2. Choose rule member(X, cons(X, Xs)).
Step 3. Rename into member(X16, cons(X16,
Xs17)).
Step 4. Use unification: X = X16, john = X16, Xs17 = cons(mary,
nil) solves as X = john, X16 = john, Xs17 = cons(mary,
nil).
Step 5. Unification with fact was success. Display result.
Step 6. Choose rule member(X, cons(Y, Ys)) :- member(X, Ys).
...
factorial(0, 1). factorial(N, F) :- N > 0, factorial(N-1, F1), F is N * F1.
Try it out. What is the result of fac(3,X)?
3-1-1-1 > 0?
Does it succeed? Does it fail? If so, why? What happens next?
3-1-1-1 > 0.
at the Prolog interpreter. What result do you get?
factorial(3-1-1-1,X), that is, factorial(sub(sub(sub(3,
1), 1, 1), X) with factorial(0, 1).)factorial by forcing evaluation of the arithmetic. What
is your code for factorial now? Confirm that factorial(3,
X) works.solvefac(N,M) :- numlist(1, M, L), member(N, L), factorial(N, M).
Try out solvefac(X,6). Explain why it works. (To see what
numlist does, just run numlist(1, 6, X).)
o functors, such as [o,o,o,o,o]. Your
task is to write a predicate move(F, T) that checks whether
one can legally move from game state F to game state
T. For example,
move([o,o,o,o,o],Y). Y = [o,o,o] ; Y = [o,o,o,o] ; fail
Hint: It is very easy to check whether T at least one less
than F:
append(S, _, F), append(T, [o], S)
It is also easy to check that T is at most half as long as
F. Append it to itself and check that you can still append
more to get F.
What is your move predicate?
win(X) :- move(X,Y), not(win(Y)).
For example,
win([o,o,o,o,o]). true ; fail.
Try out marble lists of length 1 to 10. Which ones are winning positions?