150 likes | 339 Views
Chapter 8: The Logical Paradigm. Lecturer: Xinming (Simon) Ou CIS 505: Programming Languages Fall 2010 Kansas State University. What we have covered so far:. Imperative paradigm Computes effects Functional paradigm Computes values Used ML as an example Logical paradigm
E N D
Chapter 8: The Logical Paradigm Lecturer: Xinming (Simon) Ou CIS 505: Programming Languages Fall 2010 Kansas State University
What we have covered so far: • Imperative paradigm • Computes effects • Functional paradigm • Computes values • Used ML as an example • Logical paradigm • Computes relations • Use Prolog as an example
Example relations • Parent relation: • parent(A, B) means A is B’s parent • e.g. parent(bill, mary). parent(mary, john). • Ancestor relation • Can be defined inductively: A is B’s ancestor if A is B’s parent. A is B’s ancestor if A is C’s ancestor, and C is B’s ancestor • The resulting relation is the smallest one that satisfies the above two rules.
Some definitions for Prolog • Atoms: • Any sequence of alpha-numeric characters that starts with a lower-case letter, or a single-quoted string, or a number e.g. mary, john01, ‘Mary Doe’, 100 • Variables: • Any sequence of alpha-numeric characters that starts with an upper-case letter, or an underscore “_” • e.g. Mary, _mary, _ • Literal • predicate(t1, …, tk), where tiis either an atom, a variable, or a data-structure (function applied to parameters). • e.g. parent(mary, john). parent(mother(john), john). ancestor(mother(father(john)), john).
Horn Clauses • A Horn clause is a logical clause with a single positive literal: L0∨ L1∨ … Ln • This is equivalent to L1∧ …∧Ln=> L0 In Prolog, we use “,” to mean logical and, and write implication “backward”. Each clause is concluded with a “.” L0 :- L1, …, Ln. • Example: ancestor(A, B) :- parent(A, B). ancestor(A, B) :- parent(A, C), ancestor(C, B). • We call the left-hand side of the clause its head, and the right-hand side of the clause its body. • A clause may have an empty body. e.g. parent(mother(X), X).
Variables in Clauses • All variables are implicitly universally bound at the beginning of the clause • e.g. ancestor(A, B) :- parent(A, B). Logically it is equivalent to: Forall A, B. parent(A,B) => ancestor(A, B) Thus A and B can be instantiated with any term. • An underscore “_” is a wild card and can match anything. • e.g. isParent(A) :- ancestor(A, _).
Query in Prolog • A query is in the form of a literal. The answer to the query is all the instantiations of the variables that make the literal true. • e.g. ? - ancestor(X,Y). X = bill Y = mary; X = mary Y = john; X = bill Y = john; no • Logically it is equivalent to “exists X, Y. ancestor(X,Y)?”
Execution Semantics of Prolog • When a query is issued, it is “compared” against the head of all the clauses one by one. • If a “match” is found, the body of the clause becomes the new goals • This process will iterate and may either succeed or fail. • In either case the execution will backtrack to the first “choice point”, and try another match. • This is called “SLD resolution”
Example SLD resolution ancestor(X,Y) :- parent(X,Y). ancestor(X,Y) :- parent(X,Z), ancestor(Z,Y). parent(bill,mary). parent(mary,john). • ?- ancestor(X, Y). • ?- parent(X,Y). • ?- parent(X,Z), ancestor(Z,Y). • X=bill • Y=mary • X=mary • Y=john • X=mary • Z=john • X=bill • Z=mary • ?- • Success ?- ancestor(john,Y). • ?- • Success ?- ancestor(mary,Y). • … • Failure ?- parent(mary,Y). ?- parent(mary,Z2), ancestor(Z2,Y). • Y=john • Z2=john ?- ancestor(john,Y). • ?- • Success • … • Failure
Logic deduction as a program • The advantage of Prolog is that it has both a logic meaning, and an execution semantics • Ideally you do not need to think about the SLD resolution process when writing Prolog code • A Prolog program is simply a collection of logical statements. A query is simply asking whether a fact can be derived as a logical consequence of the statements. • However… • When the result does not match your expectation, knowing the SLD resolution process will help in debugging. • Moreover, Prolog is not always declarative, which we will see in the next lecture.
Practice XSB • We will be using the XSB Prolog system • Is installed on all the departmental Linux machines • Can be downloaded from: http://xsb.sourceforge.net/ Installation is relatively hassle-free. However, if you need to compile XSB under Mac OS X Snow Leopard, please let me know and there will be special instructions.
The first simple Prolog program • Put the following Prolog statements in a text file named “ancestor.P” parent(bill, mary). parent(mary, john). ancestor(A, B) :- parent(A, B). ancestor(A, B) :- parent(A, C), ancestor(C, B). Load the file in XSB: bash-3.2$ xsb [xsb_configuration loaded] [sysinitrc loaded] XSB Version 3.2 (Kopi Lewak) of March 15, 2009 [i386-apple-darwin10.4.0; mode: optimal; engine: slg-wam; scheduling: local; word size: 64] | ?- [ancestor].
Experiment with it • Issue various queries: e.g. ?- ancestor(X,Y). ?- ancestor(bill, X). ?- ancestor(john, X). … • Change the order of the clauses and see what will happen: parent(bill, mary). parent(mary, john). ancestor(A, B) :- parent(A, C), ancestor(C, B). ancestor(A, B) :- parent(A, B).