CS 541 Lecture -*- Outline -*- * non-logical features ** Cut (!) the only control operator in prolog reduces the search space by dynamically pruning the search tree green cut: prunes fruitless paths that cannot produce solutions red cut: prunes paths that may contain solutions (negation) ------- % recursive program for membership in lists mbr(Head, [Head|Tail]). mbr(Element,[Head|Tail]) :- mbr(Element,Tail). ------- If only want membership test, want to stop as soon as found something. use cut (!, in first clause) ------- % membership test mbr1(Head, [Head|Tail]):- !. mbr1(Element,[Head|Tail]) :- mbr1(Element,Tail). ------- second clause used only if first fails. cannot generate several different answers. ------ % a transcript | ?- mbr(2,X). X = [2|_6] ; X = [_5,2|_10] ; X = [_5,_9,2|_14] | ?- mbr1(2,X). X=[2,_6] ; no ------ *** What does cut do? ! succeeds and commits Prolog to all the choices made since the parent goal was unified with the head of the clause in which the cut occurs **** cut prunes all clauses below it --------------- p :- a, b, c. b :- d, e, !, f. b :- g, h. --------------- cut prevents the second b rule from being used. **** Backtracking across cut causes whole clause to fail (fail to caller) if f fails, then the whole clause fails. think of cut as committing Prolog to a choice the goal succeeds and commits Prolog to all the choices made since the parent goal was unified with the head of the clause in which the cut occured. thus: prunes all clauses below it prunes all alternatives to its left in a clause. does not affect goals to its right in a clause. example: If b1 then b2 else b3 can be done using cut as follows a1 :- b1, !, b2. a1 :- b3. ** Negation as failure *** negation treated as unprovability (closed world assumption) not combines cut and fail (predicate that fails) ------------------ not(X) :- X, !, fail. not(X). ------------------ order essential (bad in itself, since less modular) idea is that if goal fails finitely, not succeeds but Prolog doesn't even find finite failures for sure note: if foo terminates, so does not(foo) if foo does not terminate, not(foo) may or may not halt *** good programming style avoids cut-fail, since logic disappears. difference between proving something false not being able to prove it's true(closed world) *** "not" doesn't work correctly for non-ground goals -------- unmarried_student(X) :- not(married(X)), student(X). student(bill). married(joe). ?- unmarried_student(X). no --------- X=bill should be a solution. not(married(X)) tries married(X), finds X=joe, so married succeeds, causing not(married(X)) to fail (don't try again because of cut!) (solved by reversing order of goals) double negation doesn't work as one expects ** Other non-logical stuff in Prolog *** is: allows one to use computer's arithmetic K is M+1 like assignment K := M+1 *** asserta, assertz: put rules in database *** retract: takes rule out of database allow non-monotonic reasoning, memoization, assignment