210 likes | 479 Views
Principles of logic programming Prolog - continued. 1. Cutting (pruning) backtracking: predicate cut Backtracking can be sometimes inconvenient. Example: f(X, 0) :- X < 3. % 1 f(X, 2) :- 3 =< X, X < 6. % 2 f(X, 4) :- 6 =< X. % 3 relation(X, Y) :- f(X, Y), 2 < Y.
E N D
Principles of logic programmingProlog - continued 1. Cutting (pruning) backtracking: predicate cut • Backtracking can be sometimes inconvenient. • Example: f(X, 0) :- X < 3. % 1 f(X, 2) :- 3 =< X, X < 6. % 2 f(X, 4) :- 6 =< X. % 3 relation(X, Y) :- f(X, Y), 2 < Y. ?- f(1, Y). Y = 0 ?- relation(1, Y). NO • Inefficient
Predicate cut - it always succeeds, has a side effect: cuts (prunes) backtracking (C1) H:-D1, D2, …, Dm, !, Dm+1, …, Dn. (C2) H:-A1, …, Ap. (C3) H. f(X, 0) :- X < 3, !. f(X, 2) :- 3 =< X, X < 6, !. f(X, 4) :- 6 =< X. • if condition then action1 else action2 if_then_else(Cond, Act1, Act2) :- Cond, !, Act1. if_then_else(Cond, Act1, Act2) :- Act2. • Green cut and Red cut • Green cut - only for efficiency • Red cut- modifies the correspondence between declarative and procedural interpretation of Prolog programs. 2
min1(X, Y, X) :- X =< Y, !. %green cut min1(X, Y, Y) :- X > Y. min2(X, Y, X) :- X =< Y,!. %red cut min2(X, Y, Y). min3(X, Y, Y). % different from min2 min3(X, Y, X) :- X =< Y, !. % above • Cut may limit the generative feature of Prolog member(X, [X| _]). member1(X, [X | _]) :- !. member(X, [ _ |Y]) :- member(X, Y). member1(X, [ _ |Y]) :- member1(X, Y). ?- member(X, [a, b, c]). ?-member1(X, [a, b, c]). X = a; X = a; X = b; NO X = c; NO • if withgreen cut if_then_else(Cond, Act1, Act2) :- Cond, !, Act1. if_then_else(Cond, Act1, Act2) :- not (Cond), !, Act2. 3
2 Imposing failure: predicate fail • Fail is a predicate that always fails. One of its roles - forcing backtracking and generation of several solutions. color(apple, red). color(orange, orange). color(grapes, green). color(grapes, red). which_color(X, Y):- color(X, Y), fail. ?- which_color(Fruit, Color). Fruit = apple, Color = red Fruit = orange, Color = orange Fruit = grapes, Color = green Fruit = grapes, Color = red NO which_color(X, Y):- color(X, Y), fail. which_color(_, _). % does not give the NO answer 4
Negation as failure • We can define (explain) the predefined predicate not as: • not(P) :- call(P), !, fail. • not(P). • call(P) makes the PROLOG engine evaluate the predicate P • call(P) - may make dynamic predicates in PROLOG • PROLOG - a form of nonmonotonic reasoning: closed world assumption With cut and fail we can simulate other procedural constructs (than if_then_else) % for(Variable, InitialValue, FinalValue, Step) for(I, I, I, 0). for( _, _ , _ , 0) :- !, fail. for(I, I, F, S) :- S > 0, (I > F, !, fail ; true) ; S < 0, (I < F, !, fail ; true). for(V, I, F, S) :- I1 is I + S, for(V, I1, F, S). a :- for(X, -10, 10, 3.5), write(X), tab(2), fail ; true. ?- a. -10 -6.5 -3.0 0.5 4.0 7.5 yes ;is a predefined operator - logical OR May be defined as: X ; X :- X. X ; Y :- Y. • Attention - may cause infinite loops. • for(X, -10, 10, 0). 5
clause(Head, Body) • % conc(List1, List2, ListRes) conc([], L, L). conc([First|Rest1], L2, [First|Rest3]) :- conc(Rest1, L2, Rest3). ?- clause(conc(A, B, C), Corp). A = [ ], B = _004C, C = _004C, Body = true; A = [_00F0|_00F4], B = _004C, C = [_00F0|_00FC], Head = conc (_00F4, _004C, _00FC); NO • Goal = .. [Functor | ArgList] ?- string(a, b, c) = .. X. X = [string, a, b, c] ?- a * b + c =.. L. % a * b + c = '+'('*'(a, b), c) L = [+, a *b, c] ?- a + b * c =.. L. % a + b * c = '+'(a, '*'(b, c)) L = [+, a, b *c] ?- Goal =.. [member, a, [a, b, c]]. Goal = member(a, [a, b, c]) ?- conc([1, 2], [3], [1, 2, 3]) =.. [Functor | ArgList] Functor = conc, ArgList = [[1, 2], [3], [1, 2, 3]] ?- f =.. L. L = [f] 6
Tail-recursive predicates • Intersection of two lists - not tail recursive member(Elem, [Elem|_]) :- !. member(Elem, [_|Rest]) :- member(Elem, Rest). inter([], _, []). inter([first|Rest], List2, [First|LRes]) :- member(First, List2), !, inter(Rest, List2, LRes). inter([ _ | Rest], List2, LRez) :- inter(Rest, List2, LRez). • Do we need both cuts, in member and in inter? • Tail-recursive intersection % int(List1, List2, ListaRez) % int1(List1, List2, AccList, ListRes) int(L1, L2, LRes) :- int1(L1, L2, [], LRes). int1([], _, L, L). int1([First|Rest], L, L1, L2) :- member(First,L), !, int1(First, L, [Prim | L1], L2). int1([ _ | Rest], L, L1, L2) :- int1(Rest, L, L1, L2). 7
Functional programming versus logic programming • functions relations • domain, range no clear distinction, only T/F value of predicates • relies on recursion relies on recursion conc([], L, L). conc([X|Rest], L, [X|Rest1]) :- conc(Rest, L, Rest1). plus(A, B, Rez) :- Rez is A + B. map( _ , [], _ , []). map(P, [Arg1 | RestArg1], [Arg2 | RestArg2], [X | Rest]) :- Goal =.. [P, Arg1, Arg2, X], call(Goal), map(P, RestArg1, RestArg2, Rest). ?- map(plus, [1, 2, 3, 4], [10, 20, 30, 40], Rez). Rez = [11, 22, 33, 44] ?- map(conc, [[1, 2], [a, b]], [[3, 4], [c, d]], Rez). Rez = [[1, 2, 3, 4], [a, b, c, d]] 8
Notes on PROLOG implementations Warren Abstract Machine (David Warren, UK) • WAM defines an abstract architecture =an instruction set that allows emulation and/or translation to native machine code. • WAM is a stack-based architecture, sharing some similarities with imperative languages: call/return instructions, local environment + support for unification and backtracking. The major data areas of the WAM are: • Heap: store the complex data structures - lists and compound terms - created during the execution. • Local Stack: same purpose of the control stack in the implementation of imperative languages: called environments, created upon entering a new clause (i.e., a new ``procedure''), store the local variables of the clause and the control information required for ``returning'' from the call. • Choice Point Stack: choice points encapsulate the execution state for backtracking purposes. • A choice point is created whenever a call having multiple possible solution paths. Each choice point must contain sufficient information to restore the status of the execution at the time of creation of the choice point, and should keep track of the remaining unexplored alternatives. 9
Trail Stack: during an execution variables can be instantiated. • During backtracking these bindings need to be undone (to restore the previous state of execution). • Bindings that can be subject to this operation are registered in the trail stack. Each choice point records the point of the trail where the undoing activity needs to stop. • Code Area: it is used to store the compiled code of the program. • Being a dynamically typed language, Prolog requires a type information to be associated with each data object. In the WAM, Prolog terms are represented as tagged words. Each word is composed by a tag, identifying the type of the object (e.g. atom, list, etc.), and by a value (e.g. atom name, pointer to the first molecule of a list, etc.). Alternatives • Compile to WAM and Emulate WAM instructions • Other alternative: Native Code Compilation: generate directly machine language code from the compilation of Prolog programs (Quintus and SICStus) 10
BinProlog • BinProlog is based on the idea of continuation passing. Prolog programs are transformed into binary logic programs--i.e. Prolog programs with at most one literal in the body. This is realized by making explicit the transfer of the continuation of each subgoal, as a new argument. • Given the PROLOG program p(a, b). p(X, Y) :- q(X, Z), r(Z, Y). • it is transformed into the following binary program p(a, b, Cont) :- call(Cont). p(X, Y, Cont) :- q(X, Z, r(Z, Y, Cont)). • Thus, the continuation is passed along as an additional argument and executed when a unit clause (a fact) is encountered. • BinProlog has been implemented as a heap-only system (i.e., no concept of environment is introduced). The fact that the abstract machine has been specialized to binary programs allowed to considerably reduce the number of instructions required and facilitated the introduction of a wide variety of optimizations. 11
Rule-based languages • Rules = chunks of deductive knowledge if the engine does not start Left hand side or and the lights are off antecedent then the battery is down Right hand side or consequent if X_engine_start = no and X_lights = off then X_battery = broke • Facts (car1_engine_start no) (car1_lights off)
Working memory RBS Architecture Problem instance (input) Knowledge base Inference engine Selection of rules Results (output) 13
Control cycle of a RBS • Match • Select • Execute Control strategy • Criteria for rule selection • Direction of application of rule • backward chaining • forward chaining initialize WM with problem instance - facts repeat - build conflict set - select one rule for execution according to strategy - execute rule and add consequent to WM until solution found Prolog - special case of RBS What control strategy?
Rule-based languages • MYCIN, EMYCIN, M1 • backward chaining • apply all rules • use certainty factors • OPS5 • facts, rules • Rete algorithm ("Rete: A Fast Algorithm for the Many Pattern/ Many Object Pattern Match Problem", Charles L. Forgy, Artificial Intelligence 19(1982), 17-37) • forward chaining • rule selection: specificity, most recent facts matched
CLIPS (NASA 1995) http://www.siliconvalleyone.com/clips.htm • C Language Integrated Production System • supports: rule-based, object-oriented and procedural programming style • written in C • can be embedded within procedural code, called as a subroutine, and integrated with languages such as C, FORTRAN and ADA • objects, facts, rules • Rete algorithm • forward chaining • integer values for rule priority • last added rule (first in / first out) • A CLIPS example follows 16
CLIPS (deffacts initial-phase (phase choose-player)) (deffacts take-sticks-information (take-sticks (how-many 1) (for-remainder 1)) (take-sticks (how-many 1) (for-remainder 2)) (take-sticks (how-many 2) (for-remainder 3)) (take-sticks (how-many 3) (for-remainder 0))) ; IF ; The phase is to choose the first player, and ; The human has given a valid response ; THEN ; Remove unneeded information, and ; Indicate whose turn it is, and ; Indicate that the pile size should be chosen (defrule good-player-choice ?phase <- (phase choose-player) ?choice <- (player-select ?player&:(or (eq ?player c) (eq ?player h))) => (retract ?phase ?choice) (assert (player-move ?player)) (assert (phase select-pile-size))) 17
JESS - the Rule Engine for the Java Platform (Sandia National Laboratories) http://herzberg.ca.sandia.gov/jess/ • Jess is a rule engine and scripting environment written entirely in (Sun's) Java; • Jess was originally inspired by CLIPS, but has grown into a distinct Java-influenced environment; • Jess is building Java applets and applications based on rules; • For some problems it is faster than CLIPS itself (using a good JIT compiler) ; • The core Jess language is still compatible with CLIPS, in that many Jess scripts are valid CLIPS scripts and vice-versa; • Like CLIPS, Jess uses the Rete algorithm for pattern matching; • Jess adds features to CLIPS, including backwards chaining and the ability to manipulate and directly reason about Java objects; • Jess is also a Java scripting environment, from which you can create Java objects and call Java methods without compiling any Java code. 18
(deffunction max (?a ?b) Jess (if (> ?a ?b) then (return ?a) else (return ?b))) TRUE Jess> (deffunction change-baby () (printout t "Baby is now dry" crlf)) TRUE Jess> (defrule do-change-baby "If baby is wet, change baby's diaper." (baby-is-wet) => (change-baby)) 19
Jess • create and manipulate Java objects directly from Jess • create a Java Hashtable and add a few String objects to it, then lookup one object and display it Jess> (bind ?ht (new java.util.Hashtable)) <External-Address:java.util.Hashtable> Jess> (call ?ht put "key1" "element1") Jess> (call ?ht put "key2" "element2") Jess> (call ?ht get "key1") "element1" 20