Upload
dinhanh
View
219
Download
0
Embed Size (px)
Citation preview
Collaboration and ManagementDana Fisman
1
Principles ofProgrammingLanguages
Lesson 22 – An Introduction to Logic Programming –Logic Programming (“Pure Prolog”)
www.cs.bgu.ac.il/~ppl172
Review of Last Lecture
RelationalLogic
Programming
Logic Programming
Prolog
How does it look like?
What is the meaning?
What is the execution alg?
Operational Semantics for LP
Interpreter of LP uses two main procedures:
o Answer-query(P,Q) aka ProofTree(P,Q)
Builds a proof tree for Q wrt. P
returns a substitution s to the variables of Q showing Q holds (or true if there are no variables)
or fail if no substitution will make the formula true (or false if there are no variables)
o Unify(A,B)
returns a substitution s such that s = mgu(A,B)
or Fail if A and B cannot be unified
Unify
Goal of Unify(A,B): find the most general unifier.
Example:
Unify( p(X,3,X,W), p(Y,Z,4,W) ) ==> {X=4, Y=4, Z=3}
Indeed:
p(X, 3, X, W)◦{X=4, Y=4, Z=3} = p(4, 3, 4, W)
p(Y, Z, 4, W)◦{X=4, Y=4, Z=3} = p(4, 3, 4, W)
Disagreement Set
The disagreement set of two atomic formulas A and B is the set of left most symbols on which the formulas disagree.
Examples:
d-s(p(X,3,X,W), p(Y,Z,4,W)) = {X,Y}.
d-s(p(5,3,X,W), p(5,3,4,W)) = {X,4}.
Unify - A unification algorithmSignature: unify(A, B)Type: [atomic-formula * atomic-formula -> a substitution or FAIL]Postcondition: result = mgu(A, B) if A and B are unifiable or FAIL, otherwise
unify(A, B) return unify_h(A, B, {})
unify_h(A, B, s)
if A’s top pred is different than A’s top pred (in name or arity) return FAIL
Let A’ = A sLet B’ = B s if A’ = B’
return selse
let D = disagreement-set(A’, B’)if D = {X, t} /* X is a variable; t is a term */
let s’ = s {X = t}unify_h(A’, B’, s’)
elsereturn FAIL
Unify - example
unify[ p(X, 3, X, W), p(Y, Y, Z, Z) ] ==>
unify_h[p(X, 3, X, W), p(Y, Y, Z, Z), {} ] ==>
D = {X, Y}
unify_h[p(Y, 3, Y, W), p(Y, Y, Z, Z), {X = Y} ] ==>
D = {Y, 3}
unify_h[p(3, 3, 3, W), p(3, 3, Z, Z), {X = 3, Y= 3} ] ==>
D = {Z, 3}
unify_h[p(3, 3, 3, W), p(3, 3, 3, 3), {X = 3, Y= 3, Z = 3} ] ==>
D = {W, 3}
unify_h[p(3, 3, 3, 3), p(3, 3, 3, 3), {X = 3, Y= 3, Z:= 3, W = 3} ] ==>
{X = 3, Y = 3, Z = 3, W = 3}
answer-query: an interpretation algorithm for LP
Input:
A query Q ?- Q1, ..., Qn. Each component is called goal
A program P , with numbered rules
A goal selection policy Gsel
A rule selection policy Rsel
Output:
A set of (possibly partial) substitutions for variables of Q.
Operational Semantics for LPMethod: Build a node N for the given query Q
From current node N:
If it is a success leaf (N = true),
o extract answer and return it
o Backtrack to obtain more answers
If it is a failure leaf (N =false)
o Backtrack
If it is not a leaf node and N = (G1,…,Gn)
o select a goal Gi and
o select a rule H :- B1, …, Bk
If H can be unified with Gi unifier Substhen create a new node N’ = (G1,…Gi-1, B1, …, Bk , Gi+1,…Gn) Subs
Otherwise, create a new node N’ = false.
o Make N’ the current node.
Input: a program P and a query Q
Output: partial subs to query variables (or true/false)
Applying Answer-Query parent(abraham, isaac). %p1parent(isaac, jacob). %p2parent(sarah, isaac). %p3parent(jacob, joseph). %p4
male(abraham). %m1male(isaac). %m2male(jacob). %m3male(joseph). %m4
ancestor(A,D) :- parent(A,D). %a1ancestor(A,D) :- parent(A,P), %a2
ancestor(P,D).
anc(isaac,D)
par(isaac, P1),anc(P1,D1)
%a2 {A1=isaac,D1=D}
anc(jacob,D1)true
D=joseph
?- ancestor(isaac,D).
par(isaac, D1)
%p2 {D1=jacob}
%p2 {P1=jacob}
par(jacob, P2),anc(P2,D2)
par(jacob, D2)
true
%p4 {D2=joseph}
anc(joseph,D2)
%p4 {P2=joseph}
par(joseph, P3),anc(P3,D3)
par(joseph, D3)
false
%a1 {A2=jacob, D2=D1}
%a1 {A1=isaac,D1=D}
%a2 {A2=jacob, D2=D1}D=jacob
%a2 {A3=joseph,D3=D2}%a1 {A3=joseph, D3=D2}
false
Applying Answer-Query parent(abraham, isaac). %p1parent(isaac, jacob). %p2parent(sarah, isaac). %p3parent(jacob, joseph). %p4
male(abraham). %m1male(isaac). %m2male(jacob). %m3male(joseph). %m4
ancestor(A,D) :- parent(A,D). %a1ancestor(A,D) :- parent(A,P), %a2
ancestor(P,D).
anc(isaac,D)
anc(P1,D),par(isaac, P1)
%a2 {A1=isaac,D1=D}
?- ancestor(isaac,D).
par(isaac,
abraham)
fail
%a1
anc(P2,D),par(P2, P1),
par(isaac, P1)
%a2 {A2=P2,D2=D}
anc(P3,D),par(P3, P2),par(P2, P1),
par(isaac, P1)
%a2 {A3=P3,D3=D}
%a2%a1
par(P1,D),par(isaac, P1)
%a1 {A2=P1,D2=D}
par(isaac,
issac)
fail
par(isaac,
sarah)
fail
par(isaac,
jacob)
true
Significant kinds of proof trees
Finite success proof tree: A finite tree with a successful path.
Finite failure proof tree: A finite tree with no successful path.
Infinite success proof tree: An infinite tree with a successful path.
Infinite failure proof tree: An infinite tree with no successful path.
Decidability of Relational LP Claim:
Given a program P and a query Q in RLP, the problem
"Is Q provable from P ", denoted P ` Q
is decidable.
Proof:
The number of terms (constants/variables) and predicates appearing in P and Q is finite.
Thus, the number of possible atomic formula (i.e. goals appearing in a node of the proof tree) is finite (except for renaming).
Let N(P,Q) be that number.
Then, any path that is longer than N(P,Q) is infinite. QED
Prolog and subsets of interest
RelationalLogic
Programming
DatalogLogic
Programming
Prolog
Modeling SQL in RLP
o RLP naturally represents structured databases (tables with static columns).
o A procedure consisting of facts can represent a table in the database.
o Often databases are access via elementary SQL operations such as:
select, project, union, Cartesian product and join.
Modeling SQL in RLP
Select (rows from table r, fitting some criteria):
r1(X1, X2, X3) :- r(X1, X2, X3),
X2 \= X3.
Project (some columns from table r):
r1(X1, X3) :- r(X1, X2, X3).
Union (unite tables r and s, with identical columns):
r_union_s(X1, ..., Xn) :- r(X1, ..., Xn).
r_union_s(X1, ..., Xn) :- s(X1, ..., Xn).
Modeling SQL in RLP
Cartesian product (all combinations of rows from r and s):
r_X_s(X1, ..., Xn, Y1, ..., Ym) :-
r(X1, ..., Xn ),
s(Y1, ..., Ym).
Natural Join (join tables r and s, with mutual column X):
r_join_s(X1, ..., Xn, X, Y1, ..., Ym) :-
r(X1, ..., Xn, X ),
s(X, Y1, ..., Ym).
Prolog and its subsets
RelationalLogic
Programming
Logic Programming
Prolog
Logic Programming
The only difference between RLP and LP is that a
functor symbol is added to the syntax
Functors are used to represent composite data
structures.
course(ppl, time(Sun,14,16), location(35,310)).
course(ppl, time(Mon,14,16), location(32,307)).
course(ppl, Sun, 14, 16, 35, 310).
course(ppl, Mon, 14, 16, 32, 307).
Logic Programming
This addition of functors has significant implication:
• the resulting logic is Turing Complete (recursively
enumerable).
• and thus partially decidable.
• Implementation requires a more complex unification
algorithm.
Logic Programming – Terms Syntax
Terms are now define inductively:
Base
A constant is a term
A variables is a term
Inductive step
If t1, . . . , tn are terms and f is a functor symbol
then f(t1, . . . , tn) is a term.
Atomic formula in FLP - examples
parent(juliet, Child)
course(ppl, time(Mon,14,16), location(32,307)).
member(cube(red(X)), Lst)
ancestor(mary, sister_of(john))
p(f(f(f(g(a,g(b,c))))))Constants: a, b, cFunctors: f,g,p
Functors: cube, red, memberVariables: X, Lst
Constants: ppl, Mon, 14, 16, 32, 307Functors: time, location, course
Constants: john, maryFunctors: sister_of, ancestor
LP – Concrete Syntax Extension
<term> ==> <constant> | <variable> | <composite-term>
<composite-term> ==> <functor> ( (<term> , )* <term> )
<functor> ==> <constant>
LP – Abstract Syntax Extension
<term>:
Kinds: <constant>,<variable>, <composite-term>
<composite-term>:
Components: Functor: <constant>Term: <term>. Amount: >=1. Ordered.
Example – power of functors
To show the power of functors, we will write a small program in pure Prolog that
o defines what are formulas in conjunctive normal form (CNF)
o provides a procedure to transform a formula not in CNF to an equivalent formula in CNF
Credit for the example: Marcin Judinski
PL – CNF Exampleo: ORa: ANDn: NEG
Example: Defining CNF
monomial(X) :- atom(X). monomial(neg(X)) :- atom(X).
disjunction(X) :- monomial(X). disjunction(or(X,Y)) :- disjunction(X), disjunction(Y).
cnf(X) :- disjunction(X). cnf(and(X,Y)) :- disjunction(X), disjunction(Y).cnf(and(X,Y)) :- cnf(X), cnf(Y).
?- atom(foo).
true
?- monomial(bar).
true
?- monomial(neg(bar)).
true
?- monomial(and(bar)).
false
Example: Defining CNF
monomial(X) :- atom(X). monomial(neg(X)) :- atom(X).
disjunction(X) :- monomial(X). disjunction(or(X,Y)) :- disjunction(X), disjunction(Y).
cnf(X) :- disjunction(X). cnf(and(X,Y)) :- disjunction(X), disjunction(Y).cnf(and(X,Y)) :- cnf(X), cnf(Y).
?- disjunction(foo).
true
?- disjunction(or(neg(foo),bar)).
true
?- disjunction(and(neg(foo),bar)).
false
?- disjunction(neg(foo)).
true
Example: Defining CNF
monomial(X) :- atom(X). monomial(neg(X)) :- atom(X).
disjunction(X) :- monomial(X). disjunction(or(X,Y)) :- disjunction(X), disjunction(Y).
cnf(X) :- disjunction(X). cnf(and(X,Y)) :- disjunction(X), disjunction(Y).cnf(and(X,Y)) :- cnf(X), cnf(Y).
?- cnf(and(neg(foo),bar)).
true
?- cnf(or(neg(foo),and(bar,moo))).
false
?- cnf(and(neg(foo),or(bar,moo))).
true
?- cnf(or(neg(foo),bar)).
true
PL – CNF ExampleNow we would like to define a procedure with
input: a boolean formula (using and,or,neg)
output: an equivalent formula in CNF
% Signature: givecnfequiv(boolform)/1% Purpose: Prints a formula cnf that is equivalent % to boolform is in CNF
% Signature: cnfequiv(boolform, cnf)/2 % Purpose: Transforms a boolean formula to an equivalent % one in CNF% Postcondition: cnf is equivalent to boolform in CNF% Precondition: boolform is a boolean formula % and cnf is a variable
This procedure will invoke
Ex. Defining givecnfequiv
givecnfequiv(X) :- cnfequiv(X,Y), write(Y).
cnfequiv(X,Y) :- transform(X,Z), cnfequiv(Z,Y).cnfequiv(X,X).
?- cnfequiv(or(neg(foo),and(bar,moo)) , X).
X = and(or(neg(foo), bar), or(neg(foo), moo))
?- givecnfequiv(or(neg(foo),and(bar,moo))).
and(or(neg(foo), bar), or(neg(foo), moo))true
Ex. Defining transformtransform(neg(neg(X)),X). % eliminate double negation
transform(neg(and(X,Y)), or(neg(X),neg(Y))). % De Morgantransform(neg(or(X,Y)), and(neg(X),neg(Y))). % De Morgan
% distribution transform(or(X,and(Y,Z)), and(or(X,Y),or(X,Z))). transform(or(and(X,Y),Z), and(or(X,Z),or(Y,Z))).
% recursion to transform sub termstransform(or(X1,Y), or(X2,Y)) :- transform(X1,X2). transform(or(X,Y1), or(X,Y2)) :- transform(Y1,Y2).
transform(and(X1,Y), and(X2,Y)) :- transform(X1,X2). transform(and(X,Y1), and(X,Y2)) :- transform(Y1,Y2).
transform(neg(X1),neg(X2)) :- transform(X1,X2).
Ex. Defining transformtransform(neg(neg(X)),X). % eliminate double negation
transform(neg(and(X,Y)), or(neg(X),neg(Y))). % De Morgantransform(neg(or(X,Y)), and(neg(X),neg(Y))). % De Morgan
% distribution transform(or(X,and(Y,Z)), and(or(X,Y),or(X,Z))). transform(or(and(X,Y),Z), and(or(X,Z),or(Y,Z))).
% recursion to transform sub termstransform(or(X1,Y), or(X2,Y)) :- transform(X1,X2). transform(or(X,Y1), or(X,Y2)) :- transform(Y1,Y2).
transform(and(X1,Y), and(X2,Y)) :- transform(X1,X2). transform(and(X,Y1), and(X,Y2)) :- transform(Y1,Y2).
transform(neg(X1),neg(X2)) :- transform(X1,X2).
PL – Operational Semantics
The abstract interpreter AnswerQuery(P,Q) for RLP applies to LP as well.
The only difference is that the unification algorithm has to be extended to handle the richer term structure, which now includes functors that can be nested within other functors.
LP - Unification
- unify(member(X,tree(X,Left,Right)) , member(Y,tree(9,void,tree(3,void,void)))) ==>
{Y=9, X=9, Left=void, Right=tree(3,void,void)}
− unify(t(X, f(a), X), t(g(U), U, W)) ==>
{X=g(f(a)), U=f(a), W=g(f(a))}
− unify(t(X, f(X), X), t(g(U), U, W)) ==>
fails
Unify – in LPSignature: unify(A, B)Type: [atomic-formula * atomic-formula -> a substitution or FAIL]Postcondition: result = mgu(A, B) if A and B are unifiable or FAIL, otherwise
unify(A, B) return unify_h(A, B, {})
unify_h(A, B, s)
if A’s top pred is different than A’s top pred (in name or arity) return FAIL
Let A’ = A sLet B’ = B s if A’ = B’
return selse
let D = disagreement-set(A’, B’)if D = {X, t} and X does not occur in t
let s’ = s {X = t}unify_h(A’, B’, s’)
elsereturn FAIL
The occur check constraint
LP as Programming Language?
Can we call Pure Prolog a programming language?
o It has the required 3:
Syntax, Semantics, Operational semantics
To be called a general purpose programming logic it also has to be Turing Complete.
o We should be able to implement any RE function in it.
Expressivity and Decidability LP
Claim:
LP is Turing-Complete.
Claim:
LP is only partially decidable.
One can write a short LP program that implements a
Turing Machine.
The finiteness algorithm we used for RLP does
no longer hold.
In the presence of functorsthat can be nested within each other,
the number of different atomic formulas is unbounded.
How can this be proven?
Expressivity of Prolog and its subsets
RelationalLogic
Programming
Logic Programming
Prolog
Not Turing Complete
Turing Complete
Turing Complete
Sch
eme
L5
only primitive ops and types
What about our Scheme Subsets?
L3cons
carcdr '() list
…
L2cond lambda
L1define
L4letrec
Which is the smallest one which is Turing
Complete?
Turing Complete
RelationalLogic
Programming
Logic Programming
Prolog
Not Turing Complete
Turing Complete
Turing Complete
So, why do we need to extend “Pure Prolog”?
Expressivity of Prolog and its subsets
Before we go into “Full Prolog”, let’s try to
implement some of these ourselves.