An introduction to Logic Programming

93
An introduction to Logic Programming Chapter 6

description

An introduction to Logic Programming. Chapter 6. Chapter topics. Introduction Relational Logic Programming : specify relations among entities Logic Programming : data structures: lists, binary trees, symbolic expressions, natural numbers (church) Prolog : arithmetic , cuts, negation - PowerPoint PPT Presentation

Transcript of An introduction to Logic Programming

Page 1: An introduction to Logic Programming

An introduction to Logic Programming

Chapter 6

Page 2: An introduction to Logic Programming

2

Chapter topics

1. Introduction2. Relational Logic Programming: specify relations

among entities3. Logic Programming: data structures: lists, binary

trees, symbolic expressions, natural numbers (church)

4. Prolog: arithmetic, cuts, negation5. Meta-circular Interpreters for Logic Programming

Page 3: An introduction to Logic Programming

3

Logic Programming: Introduction

• Origin: automate the process of proving logical statements

• Mind switch:– Formula procedure declaration⇔– Query procedure call⇔– Proving computation⇔

Page 4: An introduction to Logic Programming

4

Logic Programming: Introduction

Every programming language has:• Syntax: set of formulas (facts and rules)• Semantics (set of answers)• Operational Semantics (how to get an

answer):– Unification– Backtracking

Page 5: An introduction to Logic Programming

Logic Programming: Introduction• The building blocks of LP expressions are formulas:

formulas defined relations. For example, formula p(X,Y) - a relation between X and Y called p.

• axioms - are the knowledge base. axioms have the form:X1,X2,...,Xk H B1 and B2 ... and Bn

• A query - claim that the computation is attempting to proof.A query has the form X1,X2,...,Xk Q1 and Q2 ... and Qm

A typical logic programming answer "X1=..., ... Xk=... also X1 =..., ... Xk=... "

• Operational semantics: set of axioms procedure definitionquery procedure applicationinterpretation prove query via program

5

Page 6: An introduction to Logic Programming

6

Logic programming modelKowalski's interpretation:

An axiom H B1 and B2 ... and Bn represents a procedure

• H is the procedure’s head and the Bi’s are its body• To solve (execute) H, we recursively solve B1 ... Bn

Page 7: An introduction to Logic Programming

7

Relational LP

• a computational model based on Kowalski's interpretation

• The Prolog language ('70) - contains RLP + additional programming features

Page 8: An introduction to Logic Programming

8

Relational LP - Syntax• atomic formula:predicate_symbol(term1, ..., termn)

• predicate symbols start with lowercase• terms:– symbols (representing individual constants)– variables (start with uppercase or _ for anonymous)

Page 9: An introduction to Logic Programming

9

Relational LP - Semantics• Values: – all atomic values are symbols (typeless)– Very few primitive predicates, such as

= (unification), \=, true, false • Computation output: – an answer to a query.– An answer to a query is a (possibly partial)

substitution (assignment) of query variables.

Page 10: An introduction to Logic Programming

10

Relational LP Syntax - formulas• atomic formula:Syntax: predicate_symbol(term1,...,termn)Examples:male(moshe)color(red)parent(reuven, moshe)parent(moshe, rina)parent(Parent, Child)ancestor(A,D)address(_City, hertzel, 20)• The only difference between predicates and individual constant

symbols are their context/location.

Page 11: An introduction to Logic Programming

11

Relational LP Syntax - Procedures• A fact is an assertion of an atomic formula. Syntax: H. where H is an atomic formula.Examples:parent(rina, moshe).color(red).ancestor(A,A).

• Variables in facts are universally quantified. "for all A, it holds that ancestor(A,A)".

• Procedures are an ordered collection of axioms (facts and rules) sharing the same predicate name and arity.

Page 12: An introduction to Logic Programming

12

% Signature: parent(Parent, Child)/2% Purpose: Parent is a parent of Childparent(rina, moshe).parent(rina, rachel).parent(rachel, yossi).parent(reuven, moshe).% Signature: female(Person)/1% Purpose: Person is a female.female(rina).female(rachel).

• Predicates have arity (no. of parameters). specified in /n in the comment above the procedure.• not necessarily unique

Page 13: An introduction to Logic Programming

13

Relational LP Syntax - QueriesA query has the syntax:?- Q1, Q2, . . . , Qn. where the Qi are atomic formulas. Meaning: Assuming the program axioms, do Q1 and ... and Qn hold? ',' means conjunction.For example, ?- parent(rina, moshe).

"Is rina a parent of moshe?”A computation is a proof of a query, returns:true ;false. user requests another answer

Page 14: An introduction to Logic Programming

14

Relational LP Syntax - QueriesA query has the syntax:?- Q1, Q2, . . . , Qn. where the Qi are atomic formulas. Meaning: Assuming the program axioms, do Q1 and ... and Qn hold as well? ',' means conjunction.For example, ?- parent(rina,X).

"Does there exist an X which is a child of rina?"X = moshe ;X = rachel. • Variables in queries are existentially quantified.

Page 15: An introduction to Logic Programming

15

Relational LP Syntax - Queries"Is there an X which is a child of rina, and is also a parent of some Y?"?- parent(rina,X),parent(X,Y).X = rachel,Y = yossi."Find two parents of moshe?":?- parent(X,moshe),parent(Y,moshe).X = rina,Y = rina ;X = rina,Y = reuven ;X = reuven,Y = rina ;X = reuven,Y = reuven.

Page 16: An introduction to Logic Programming

16

Relational LP Syntax - Queries"Find two different parents of moshe?":?- parent(X,moshe),parent(Y,moshe),X \= Y.X = rina,Y = reuven ;X = reuven,Y = rina ;false.?- parent(X,moshe), X \= Y, parent(Y,moshe).false.

?- X=3.X = 3.?- X\=3.false.?- 4\=3.true.

Page 17: An introduction to Logic Programming

17

Relational LP - Syntax% Signature: loves(Someone, Somebody)/2% Purpose: Someone loves Somebodyloves(rina,Y). % rina loves everybody.loves(moshe, rachel).loves(moshe, rina).loves(Y,Y). % everybody loves himself

• Variables in axioms are universally quantified."for all Y loves(rina,Y)"can be renamed "for all X loves(rina,X)"• Using a variable in a fact is defining it. The scope is the fact itself.

Page 18: An introduction to Logic Programming

18

Relational LP - Syntax% Signature: loves(Someone, Somebody)/2% Purpose: Someone loves Somebodyloves(rina,Y). % rina loves everybody.loves(moshe, rachel).loves(moshe, rina).loves(Y,Y). % everybody loves himself

Queries:?- loves(rina,moshe).true ;false.

Page 19: An introduction to Logic Programming

19

Relational LP - Syntax% Signature: loves(Someone, Somebody)/2% Purpose: Someone loves Somebodyloves(rina,Y). % rina loves everybody.loves(moshe, rachel).loves(moshe, rina).loves(Y,Y). % everybody loves himself

Queries:?- loves(rina,X).true ;X = rina.

Page 20: An introduction to Logic Programming

20

Relational LP - Syntax% Signature: loves(Someone, Somebody)/2% Purpose: Someone loves Somebodyloves(rina,Y). % rina loves everybody.loves(moshe, rachel).loves(moshe, rina).loves(Y,Y). % everybody loves himself

Queries:?- loves(X,rina).X = rina ;X = moshe ;X = rina.

Page 21: An introduction to Logic Programming

21

Relational LP - Syntax% Signature: loves(Someone, Somebody)/2% Purpose: Someone loves Somebodyloves(rina,Y). % rina loves everybody.loves(moshe, rachel).loves(moshe, rina).loves(Y,Y). % everybody loves himself

Queries:?- loves(X,X).X = rina ;true.

this query has two answers.

Page 22: An introduction to Logic Programming

22

Relational LP Syntax - Rules• Syntax: H :−B1, . . . , Bn.is an assertion of an implication statement. The conjunction of B1, .., Bn implies the head H. Bi's and H are atomic formulas.

% Signature: mother(Mum, Child),% Purpose: Mum is a mother of Childmother(Mum, Child) :- parent(Mum, Child),

female(Mum).

• Variables occurring in rule heads are universally quantified. The lexical scope of the variable is the rule.

• A variable can multiple times in the head.• variables are bound within a rule.

Page 23: An introduction to Logic Programming

23

Relational LP Syntax - Rules% Signature: mother(Mum, Child),% Purpose: Mum is a mother of Childmother(Mum, Child) :- parent(Mum, Child),

female(Mum).

?- mother(M,C).M = rina,C = moshe ;M = rina,C = rachel ;M = rachel,C = yossi ;false.

Page 24: An introduction to Logic Programming

24

Relational LP Syntax - Rules% Signature: mother(Mum, Child),% Purpose: Mum is a mother of Childmother(Mum, Child) :- parent(Mum, Child),

female(Mum). “Find a two-different-kids mother”?- mother(M,C1),mother(M,C2),C1\=C2.M = rina,C1 = moshe,C2 = rachel ;M = rina,C1 = rachel,C2 = moshe ;false.

Page 25: An introduction to Logic Programming

25

Relational LP Syntax - Rulesthe ancestor relationship - a recursive rule that computes the

transitive closure of the parent relationship.% Signature: ancestor(Ancestor, Descendant)/2% Purpose: Ancestor is an ancestor of Descendant.ancestor(Ancestor, Descendant) :-

parent(Ancestor, Descendant).ancestor(Ancestor, Descendant) :-

parent(Ancestor, Person),ancestor(Person, Descendant).

• Variables occurring in the rule body and not in the head are existentially quantified.

"for all Ancestor and for all Descendant, ancestor(Ancestor, Descendant) if there exists some Person such that parent(Ancestor, Person) and ancestor(Person, Descendant)."

Page 26: An introduction to Logic Programming

26

Relational LP Syntax - Rulesthe ancestor relationship - a recursive rule that computes the

transitive closure of the parent relationship.% Signature: ancestor(Ancestor, Descendant)/2% Purpose: Ancestor is an ancestor of Descendant.ancestor(Ancestor, Descendant) :-

parent(Ancestor, Descendant).ancestor(Ancestor, Descendant) :-

parent(Ancestor, Person),ancestor(Person, Descendant).

?- ancestor(rina,D).D = moshe ;D = rachel ;D = yossi ;false.

Page 27: An introduction to Logic Programming

27

Relational LP Syntax - Rulesthe ancestor relationship - a recursive rule that computes the

transitive closure of the parent relationship.% Signature: ancestor(Ancestor, Descendant)/2% Purpose: Ancestor is an ancestor of Descendant.ancestor(Ancestor, Descendant) :-

parent(Ancestor, Descendant).ancestor(Ancestor, Descendant) :-

parent(Ancestor, Person),ancestor(Person, Descendant).

?- ancestor(A,yossi).A = rachel ;A = rina ;false.

• The reported result/functionality depends on the variables and their location in the query.

Page 28: An introduction to Logic Programming

28

Relational LP Syntax - Rulesancestor1(Ancestor, Descendant) :-

parent(Ancestor, Descendant).ancestor1(Ancestor, Descendant) :- ancestor1(Person,

Descendant),parent(Ancestor, Person).

?- ancestor1(A,yossi).A = rachel ;A = rina ;ERROR: Out of local stack?- ancestor1(rina,yossi).true ;ERROR: Out of local stack• This procedure is not tail recursive.• Since this query cannot be answered using the base case, new

similar queries are infinitely created.

Page 29: An introduction to Logic Programming

29

NoteFacts can be considered as rules with an empty body.

For example, parent(rina, moshe).parent(rina, moshe):- true.have equivalent meaning.

true - is the zero-arity predicate.

Page 30: An introduction to Logic Programming

30

Concrete syntax of Relational Logic Programming<program> -> <procedure>+<procedure> -> (<rule> | <fact>)+ with identical predicate and arity<rule> -> <head> ’: -’ <body>’.’<fact> -> <head>’.’<head> -> <atomic-formula><body> -> (<atomic-formula>’,’)* <atomic-formula><atomic-formula> -> <constant> | <predicate>’(’(<term>’,’)* <term>’)’<predicate> -> <constant><term> -> <constant> | <variable><constant> -> A string starting with a lower case letter.<variable> -> A string starting with an upper case letter.<query> -> ’?-’ (<atomic-formula>’,’)* <atomic-formula> ’.’

Page 31: An introduction to Logic Programming

31

Summary - RLP Semantic and syntaxparent(rina, moshe).parent(rina, rachel).parent(rachel, yossi).parent(reuven, moshe).ancestor(Ancestor, Descendant) :- parent(Ancestor, Descendant).ancestor(Ancestor, Descendant) :- parent(Ancestor, Person),

ancestor(Person, Descendant).

?- ancestor(A,yossi).A = rachel ;A = rina ;false.

Concepts: • predicate symbol, individual constant symbol, axioms (facts/rules), query.Semantics: • individual constant symbols - entities, axioms - relations of entities.• Quantification of variables (universal/existential)• Answers are partial substitutions to query variables (or true/false indications).

Page 32: An introduction to Logic Programming

32

Operational Semantics for LP

Input: a program P and a query QInterpreter of LP:1. Unify - pattern matching between an atomic

formula from Q and a head of some rule/fact from P.

2. Answer-query (proof-tree)- Create a proof tree. Back track from a leaf if it is a "dead end" fail leaf, or if it is a success leaf and there may be additional answers to the query.

Page 33: An introduction to Logic Programming

33

UnificationThe unification operation:two atomic formulas ==> substitution

p(3, X), p(Y, 4) ==> {X = 4, Y = 3} p(X, 3, X), p(Y, Z, 4) ==> {X = 4, Z = 3, Y = 4}

• substitution - a finite mapping, s, from variables to terms, such that s(X)≠X.

Examples: s={X=4, Y=4, Z=3}{X = 4, Z = 3, U = X}, {X = 4, Z = 3, U = V }Not substitutions: {X = 4, Z = 3, Y = Y }, {X = 4, Z = 3, X = Y }

Page 34: An introduction to Logic Programming

34

Application of Substitutionatomic formula ◦ substitution ==> atomic formula'p(X, 3, X, W ) ◦ {X = 4, Y = 4} = p(4, 3, 4, W)p(X, 3, X, W ) ◦ {X = 4, W = 5} = p(4, 3, 4, 5)p(X, 3, X, W ) ◦ {X = W, W = X} = p(W, 3, W, X)

• A unifier of atomic formulas A and B is a substitution s, such that A◦s = B◦s.

• The unification operation returns a unifier.

• Goal of Unify(A,B): find the most general unifier.Unify( p(X, 3, X, W), p(Y, Z, 4, W ) ) ==> {X=4, Y=4, Z=3} 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)

• Less general unifiers {X = 4, Z = 3, Y = 4, W = 5}, {X = 4, Z = 3, Y = 4, W = 0}

Page 35: An introduction to Logic Programming

35

Instantiation and Generalization

• An atomic formula A’ is an instance of an atomic formula A if there is a substitution s such that A◦s = A’

• A is more general than A’ if A’ is an instance of A

Page 36: An introduction to Logic Programming

36

Most General Unifier (MGU)

• mgu of atomic formulas A and B is a unifier s of A and B such that A◦s = B◦s is more general than all other instances of A and B obtained by applying a unifier

Page 37: An introduction to Logic Programming

37

Combination of substitutions

s ◦ s'1. s' is applied to the terms of s2. A variable X for which s(X) is defined, is removed from the

domain of s'3. The modified s' is added to s.4. Identity bindings are removed.{X = Y, Z = 3, U = V } ◦ {Y = 4, W = 5, V = U, Z = X} = {X = 4, Z = 3, Y = 4, W = 5, V = U}.

Page 38: An introduction to Logic Programming

38

Disagreement Set

• The disagreement set of atomic formulas is the set of left most symbols on which the formulas disagree.

disagreement-set(p(X, 3, X, W ), p(Y, Z, 4, W )) = {X, Y }.disagreement-set(p(5, 3, X, W ), p(5, 3, 4, W )) = {X, 4}.

Page 39: An introduction to Logic Programming

39

Unify - A unification algorithmSignature: unify(A, B)Type: atomic-formula*atomic-formula -> a substitution or FAILPost-condition: result = mgu(A, B) if A and B are unifiable or FAIL, otherwise

Page 40: An introduction to Logic Programming

40

Unify - examples1. unify[ p(X, 3, X, W), p(Y, Y, Z, Z) ] ==>

help[ {} ] ==>D = {X, Y}help[ {X = Y } ] ==>D = {Y, 3}help[ {X = 3, Y = 3 } ] ==>D = {Z, 3} ]help[ {X = 3, Y = 3, Z = 3 } ] ==>D = {W, 3}help[ {X = 3, Y = 3, Z = 3, W = 3 } ] ==>{X = 3, Y = 3, Z = 3, W = 3 }

2. unify[ p(X, 3, X, 5), p(Y, Y, Z, Z) ] ==>FAIL

Page 41: An introduction to Logic Programming

41

Properties of unify(A, B) algorithm:

• The algorithm always terminates.

• Unification is a generalization of Pattern matching

• If B does not include variables and A does not include repeated variable occurrences, the time complexity can be linear.

Page 42: An introduction to Logic Programming

42

Operational Semantics for LP

Interpreter of LP:1. Unify - pattern matching between an atomic

formula from Q and a head of some rule/fact from P.

2. Answer-query (proof-tree)- Create a proof tree. Back track from a leaf if it is a "dead end" fail leaf, or if it is a success leaf and there may be additional answers to the query.

Page 43: An introduction to Logic Programming

43

answer-query: an interpretation algorithm for LP

Input:A query: Q = ?- Q1, ..., Qn. Each component is called goalA program P , with numbered rules (denoted by number(R))A goal selection policy Gsel

A rule selection policy Rsel

Output: A set of (possibly partial) substitutions for variables of Q.

General Idea:Repeated effort to select a goal using roles.

Page 44: An introduction to Logic Programming

44

answer-query Algorithm

1. PT := proof-tree(make_node(Q))2. Return {s | s labels(Success(P T ))/Q }, ∈

where Success(PT) is the set of Success nodes of P T , and labels/Q is the restriction of the substitutions in labels to the variables of Q.

Page 45: An introduction to Logic Programming

45

proof-tree(current_node)If label(current_node) is ?- true, ..., true.

1. Mark current_node as a Success node 2. If the path from the tree root to current_node is labeled with the substitutions s1, . . . , sn, label current_node with the substitution s1 ◦ s2 ◦ . . . ◦ sn

Else 1. Select a goal G true in label(current_node) according to Gsel. 2. Rename variables in every rule and fact of P . 3. While has-next?(iterator(current_node)):

(a) Advance iterator: next(iterator(current_node)) (b) Rule selection: Starting from iterator(current_node), and according to Rsel, select a rule R = [A :- B1, ..., Bm.] such that Unify(A, G) = s' succeeds with the unifying substitution s'.

(c) Rule application: if a rule R is selected then i. Construct a new query node by removing G, adding the body of R, and applying s' to the resulting query: new_node = make_node([label(current_node)−G+B1,...,Bm]◦s') ii. Add a child node and start a new proof: add_child(current_node, < s', number(R) >, (new_node)) proof-tree(new_node)

Page 46: An introduction to Logic Programming

46

Comments about answer-query• Variable renaming according to depth in tree. Xi at depth i.

• Unify(A,G), where G is the selected goal and A the head of the

selected rule. – Let XG is a variable from G and XA a variable of A

– Selecting XA=XG or XG=XA does not change query results.

– Selecting XA=XG leaves the query variables in the tree.

• The goal and rule selection decisions can affect the performance of the interpreter.

Page 47: An introduction to Logic Programming

47

Example 6.5% Signature: father(F,C)/2parent(abraham,isaac). %1parent(isaac, jacob). %2parent(haran,lot). %3parent(haran,yiscah). %4parent(haran,milcah). %5% Signature: male(P)/1male(isaac). %1male(lot). %2% Signature: son(C, P)/2son(X, Y) - parent(Y, X), male(X). %1% Signature: ancestor(Ancestor, Descendant)/2anc(Anc, Des) :- parent(Anc, Des). %1anc(Anc, Des) :- parent(Anc, Person),

%2anc(Person, Des).

Page 48: An introduction to Logic Programming

48

?- son(S, haran).

Page 49: An introduction to Logic Programming

?- anc(abraham, D).

49

What happens if rules 1 and 2 of 'anc' are switched?

Page 50: An introduction to Logic Programming

What happens if bodies 1 and 2 in rule 2 of 'anc' are switched?

Page 51: An introduction to Logic Programming

51

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. In this case it is important not to explore an infinite path. For Prolog: Tail recursion is safe.

• Infinite failure proof tree: An infinite tree with no successful path.

Page 52: An introduction to Logic Programming

52

6.1.6 Relational logic programming and Structured Query Language (SQL) operations

• RLP naturally represents structured databases (tables with static columns).

• A procedure consisting of facts can represent a table in the database.

• Often databases are access via elementary SQL operations such as: select, project, union, Cartesian product and join.

• 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).

Page 53: An introduction to Logic Programming

53

6.1.6 Relational logic programming and Structured Query Language (SQL) operations

• 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).• 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).

Page 54: An introduction to Logic Programming

54

6.1.5.3 Halting problem, RLP decidabilityLRLP = {(P,Q) | P|- Q in RLP syntax}Claim: Given a program P and a query Q, 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

• Most programming languages are only partially decidable (recursively enumerable/TM recognizable)

Page 55: An introduction to Logic Programming

55

Prolog

LP

6.2 Logic Programming

Relational LP

typeless atomic terms, type safedecidablemulti-directional

functors, typeless composite terms, type safepartially decidable, multi-directional

arithmetics, uni-directional dynamically typed,not type safe,system predicates (e.g. !)

Page 56: An introduction to Logic Programming

56

6.2.1 Logic ProgrammingA functor symbol is added to the syntax, to represent data structures.

Terms (definition): • constant individual symbols• variables• f(t1, . . . , tn) for terms t1, . . . , tn and a functor f.Implications• additional expressiveness (composite data structures)• the LP language is partially decidable (recursively

enumerable/TM recognizable) (in the same rank as other programming languages).

Page 57: An introduction to Logic Programming

57

6.2.1 Atomic formula in FLP - examples

parent(rina, Child)

p(f(f(f(g(a,g(b,c))))))

member(cube(red(X)), Lst)

predicate terms (a constant and a variable)

predicate a term (functors f,g combining constants a,b,c)

predicate terms (functors cube and red applied to variable X)

Page 58: An introduction to Logic Programming

58

6.2.1.1 Formalizing the syntax extension

<term> -> <constant> | <variable> | <composite-term><composite-term> -> <functor> ’(’ (<term>’,’)* <term>’)’<functor> -> <constant>

Page 59: An introduction to Logic Programming

59

6.2.2.1 Unification for terms that include functors• A substitution s is a finite mapping from variables to terms, such

that s(X) does not include X. • Unify remains the same, except for two points: 1. Disagreement set can happen within a term

- 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))}

Page 60: An introduction to Logic Programming

60

6.2.2.1 Unification for terms that include functors• A substitution s is a finite mapping from variables to terms, such

that s(X) does not include X. • Unify remains the same, except for two points: 1. Disagreement set can happen within a term2. Validation of occur check error (i.e. s(X) includes X).

− unify(t(X,f(X),X), t(g(U),U,W))

==> fails due to occur check error! Expansion is infinite

• Unify algorithm for LP is modified so that it fails if occur check error is found in the {X=t} substitution at the disagreement-set.

Page 61: An introduction to Logic Programming

61

6.2.3.2 Natural number arithmeticNatural numbers can be represented by Church numerals: The constant zero

denotes the number 0, s(0) - denotes 1, s(...s(s(0))...), n times - denotes natural number n, where s is a functor.

% Signature: natural_number(N)/1% Purpose: N is a natural number.natural_number(zero). %1natural_number(s(X)) :- natural_number(X). %2

% Signature: le(X,Y)/2% Purpose: X is less or equal Y.le(zero, X) :- natural_number(X). %1le(s(X), s(Z)) :- le(X, Z). %2

• no data structure definition - definition via use.

Page 62: An introduction to Logic Programming

62

6.2.3.2 Natural number arithmetic?- le(s(s(zero)), s(s(s(s(zero))))).true.?- le(s(s(X)), s(s(s(s(zero))))).X = zero ;X = s(zero) ;X = s(s(zero)) ;false.?- le(s(s(X)), s(s(s(s(Y))))).X = Y, Y = zero ;X = zero,Y = s(zero) ;X = zero,Y = s(s(zero)) ;X = zero,Y = s(s(s(zero))) ...

multi-directional definition - Functionality depends on the locations of variables in the query.

Page 63: An introduction to Logic Programming

63

substitution for first leaf to the left{X1=zero, N=s(Z1)}{X2=Z1} {Z1=zero}= {X1=zero, N=s(zero), X2=zero, Z1=zero}

substitution for second leaf:{X1=zero, N=s(Z1)}{X2=Z1} {Z1=s(X3)} {X3=zero}= {X1=zero, N=s(s(zero)), X2=s(zero), Z1=s(zero), X3=zero}

Page 64: An introduction to Logic Programming

64

Summary

• Proof tree types• LP with functors• Unify + occur check error

Page 65: An introduction to Logic Programming

65

6.2.3.3 Lists in LP• Lists are a primitive composite data structure.• Unlike non-primitive data-structure prefix notation

f(t1, . . . , tn)list functor appears in infix notation.

• Syntax[ ] - a 0-arity functor representing the empty list.[Head|Tail] - a 2-arity functor representing a list that is

constructed from its head and its tail, where the tail is also a list.

Page 66: An introduction to Logic Programming

66

Examples?- X=[].X=[].

?- X=[a|[ ]].X = [a].

?- X = [a]. X = [a].

?- [a|[ ]] = [a].true.

?- X= [a | [ b | [] ]].X = [a, b].

?- Y = [1,2,3].Y = [1, 2, 3].

?- Y=[1,2,3], X= [a,b| Y].Y = [1, 2, 3],X = [a, b, 1, 2, 3].

?- X = [a, b, c|[d,e,f]].X = [a,b,c,d,e,f].

?- X=[1|t]. /* not a list */X = [1|t].

Page 67: An introduction to Logic Programming

67

6.2.3.3 LP lists - List membership% Signature: member(X, List)/2% Purpose: X is a member of List.member(X, [X|Xs]).member(X, [Y|Ys]) :- member(X, Ys).

% checks membership?- member(a, [b,c,a,d]). % takes an element from a list?- member(X, [b,c,a,d]). % generates a list containing b?- member(b, Z).

Page 68: An introduction to Logic Programming

68

6.2.3.3 LP lists - List concatenation% Signature: append(List1, List2, List3)/3% Purpose: List3 is the concatenation of List1 and List2.

append([], Xs, Xs).append([X|Xs], Ys, [X|Zs]) :- append(Xs, Ys, Zs).

/* addition of two lists */?- append([a,b], [c], X).

/* finds a difference between lists */?- append(Xs, [a,d], [b,c,a,d]).

/* divides a list into two lists */?- append(Xs, Ys, [a,b,c,d]).

Page 69: An introduction to Logic Programming

69

append([], Xs, Xs). %1append([X|Xs], Ys, [X|Zs] ) :- append(Xs, Ys, Zs). %2

append(Xs, [a,d], [b,c,a,d])

append(Xs1, [a,d], [c,a,d])

2{Xs=[X1|Xs1], Ys1=[a,d],X1=bZs1=[c,a,d]}

true

2{Xs1=[X2|Xs2], Ys2=[a,d],X2=cZs2=[a,d]}

append(Xs2, [a,d], [a,d])2{Xs2=[X3|Xs3], Ys3=[a,d],X3=aZs3=[d]}

1{Xs2=[], Xs3=[a,d]}

append(Xs3, [a,d], [d])

2{Xs3=[X4|Xs4], Ys4=[a,d],X4=dZs4=[]}

append(Xs4, [a,d], [])

fail

Page 70: An introduction to Logic Programming

70

6.2.3.3 LP lists - List concatenation% Signature: append(List1, List2, List3)/3% Purpose: List3 is the concatenation of List1 and List2.append([], Xs, Xs).append([X|Xs], Ys, [X|Zs]) :- append(Xs, Ys, Zs).• List prefix and suffix:prefix(Xs, Ys) :- append(Xs, Zs, Ys).suffix(Xs, Ys) :- append(Zs, Xs, Ys).• Redefine member:member(X, Ys) :- append(Zs, [X|Xs], Ys).• Adjacent list elements:adjacent(X, Y, Zs) :- append(Ws, [X,Y|Ys], Zs).• Last element of a list:last(X, Ys) :- append(Xs, [X], Ys).

Page 71: An introduction to Logic Programming

71

6.2.3.3 LP lists - List Reverse% Signature: reverse(List1, List2)/2% Purpose: List2 is the reverse of List1.reverse([], []).reverse([H|T], R) :- reverse(T, S),

append(S, [H], R).?- reverse([a,b,c,d],R).R=[d,c,b,a]?- reverse(R,[a,b,c,d]).

• Rule body ordering impacts the performance in various directions.

Page 72: An introduction to Logic Programming

72

Page 73: An introduction to Logic Programming

73

reverse([], []). %1reverse([H|T], R) :- reverse(T, S), append(S, [H], R). %2append([], Xs, Xs).%1append([X|Xs], Y, [X|Zs] ) :- append(Xs, Y, Zs). %2

reverse(RList,[a,b,c])

reverse(T1,S1), append(S1, [H1], [a,b,c])

2{Rlist=[H1|T1],R1=[a,b,c]} 2

{T1=[H2|T2], R2=S1}

fail

1{T2=[], S2=[]}

reverse(T3, S3)append(S3, [H3], S2) append(S2, [H2], S1)

append(S1, [H1], [a,b,c])

1{T1=[], S1=[]}

append([], [H1], [a,b,c])reverse(T2, S2)

append(S2, [H2], S1)append(S1, [H1], [a,b,c])

append([], [H2], S1) append(S1, [H1], [a,b,c])

1{Xs1=[H2], S1=[H2]}

append([H2], [H1], [a,b,c])

fail

2{T2=[H3|T3], R3=S2}

1{T3=[],S3=[]}

append([], [H3], S2) append(S2, [H2], S1)

append(S1, [H1], [a,b,c]) 1{Xs1=[H3], S2=[H3]}

append([H3], [H2], S1)append(S1, [H1], [a,b,c])

true

append([H3,H2], [H1], [a,b,c])

... S1=[H3,H2]

... H3=a, H2=b, H1=cRlist=[c,b,a]

...

Page 74: An introduction to Logic Programming

74

6.2.3.3 LP lists - List Reverse• An iterative version: uses the unification mechanism to accumulate the result in the second

parameter which is returned in the base case. • The help procedure is global. In Prolog all procedures are global.

% Signature: reverse(List1, List2)/2reverse(Xs, Ys):- reverse_help(Xs,[],Ys).

% Signature: reverse_help(List1, AccReversed, RevList)/2reverse_help([ ],Ys,Ys ).reverse_help([X|Xs], Acc, Ys ) :-

reverse_help(Xs,[X|Acc],Ys).

?- reverse([a,b,c],R).R=[c,b,a]?- reverse(R,[a,b,c]).ERROR: Out of local stack

Page 75: An introduction to Logic Programming

75

Prolog

LP

6.3 Prolog

RLP

typeless atomic terms, type safedecidablemulti-directional definitions

functors, typeless composite terms, type safepartially decidable, multi-directional definitions

arithmetics, uni-directional procedures dynamically typed,not type safe,system predicates (e.g. !)

Page 76: An introduction to Logic Programming

76

6.3.2 The cut operator - pruning trees

The cut system predicate, denoted !, is a Prolog built-in predicate, for pruning proof trees.

• avoiding traversing failed sub-trees.• eliminates wrong answers or infinite branches

Page 77: An introduction to Logic Programming

77

6.3.2 The cut operatorFor a node v, in which rule H :- B1, ...Bi, !, Bi+1, ..., Bn

is applied, and having a branch to a node u, in which the current goal is !, all alternative branches splitting from nodes in the path between v (including) and node u are trimmed.

v

u

Page 78: An introduction to Logic Programming

78

Example: trimming unwanted answersp(X) :- a(X).p(X) :- b(X),c(X),d(X),e(X).p(X) :- f(X).a(1). b(1). b(2). c(1).c(2).d(2).e(2).f(3).

?- p(X).X = 1 ;X = 2 ;X = 3 ;fail

Page 79: An introduction to Logic Programming

79

Example: trimming unwanted answersp(X) :- a(X).p(X) :- b(X),c(X),!,d(X),e(X).p(X) :- f(X).a(1). b(1). b(2). c(1).c(2).d(2).e(2).f(3).

?- p(X).X = 1 ;fail

Some answers were eliminated

Page 80: An introduction to Logic Programming

80

Example: trimming unwanted answersProblem domain: colored pieces, each piece has one color.color(P, red) :- red(P).color(P, black) :- black(P).color(P, unknown).red(a).black(b).

The queries to return a single solution?- color(a, Color).

Page 81: An introduction to Logic Programming

81

Example: trimming unwanted answersEliminates wrong answerscolor(P, red) :- red(P),!.color(P, black) :- black(P),!.color(P, unknown).red(a).black(b).

Page 82: An introduction to Logic Programming

82

Example: avoiding unnecessary searches (duplicate answers)

member(X,[X|Ys]). member(X,[Y|Zs]) :- member(X, Zs).

Adding cut:member(X,[X|Ys]) :- !. member(X,[Y|Zs]) :- member(X, Zs).

?- member(5, [5, 9, 24, 17, 5, 2])). % After one application the proof tree is complete.?- member(9, [5, 9, 24, 17, 5, 2])). % After 2 applications the proof tree is complete.?- member(X, [5, 9, 24, 17, 5, 2]). % Only one answer will be returned.

Page 83: An introduction to Logic Programming

83

Example: cut implements negation% Signature: not_member(Element, List)/2% Purpose:

the relation in which Element is not a member of Listnot_member(_, []).not_member(X, [Y|Ys]) :- X \= Y,

not_member(X, Ys).

Alternatively,not_member(X,Xs):- member(X,Xs),!,false.not_member(X,Xs).

Page 84: An introduction to Logic Programming

84

6.3.3 Negation in Logic Programming

• not(X) is primitive operator for negation in Prolog.• Negation by failure:

not(X) does not mean that X is false, it means that X can't be proven.

• For example, with the program:man('Adam'). woman('Eve'). ?- not(man('Abel')).true

• We can implement not, as follows:

not(Goal) :- Goal, !, false. not(Goal).

Page 85: An introduction to Logic Programming

85

6.4 Meta-circular interpreters for LP

• Based on unification and backtracking.• Two points of selection:(a) Goal selection - leftmost for Prolog.(b) Rule selection - top-to-bottom for Prolog,

with backtracking to the following rules, in case of a failure.

Page 86: An introduction to Logic Programming

86

Meta-Interpreter - version 1% Signature: solve(Goal)/1% Purpose: Goal is true if it is true when posed to

the original program P.solve( A ) :- A.

Page 87: An introduction to Logic Programming

87

Meta-interpreter - version 2% Signature: solve(Goal)/1% Purpose: Goal is true if it is true when posed to

the original program P.solve(true) :- !.solve( (A, B) ) :- !, solve(A), solve(B).solve(A) :- clause(A, B), solve(B).

Page 88: An introduction to Logic Programming

88

Comments

(A,B) is a tuple.

?- X=(Y,T).X = (Y, T).?- (X,Y)=(A,B,C,D).X = A,Y = (B, C, D).

Page 89: An introduction to Logic Programming

89

CommentsThe Prolog system predicate clause, which for a query ?- clause(A,B). selects the first program rule whose head unifies with A, and unifies B withthe rule body.append([ ],Xs,Xs).append([X|Xs],Y,[X|Zs]) :- append(Xs,Y,Zs).reverse([], []).reverse([H|T], R) :- reverse(T, S), append(S, [H], R).?- clause(append(X,[1,2], Z), Body).X = [], Z = [1,2], Body = true;X = [X1|Xs1 ], Z = [X1|Zs1], Body = append(Xs1, [1,2], Zs1).?- clause(reverse(List,RList), Body).List = [], RList = [], Body = true ;List = [_G513|_G514], Body = (reverse(_G514, _G517),append(_G517, [_G513], RList)).

Page 90: An introduction to Logic Programming

90

Meta-interpreter - version 3Pre-processing – Program transformation.

Every rule A :- B1, B2, ..., Bn in program P, is written in program P' as a fact rule(A,[B1, B2, ..., Bn]).

Program P: member(X,[X|Xa]).member(X,[Y|Ys]) :- member(X, Ys).append([ ], Xs, Xs).append([X|Xs],Ys,[X|Zs]) :- append(Xs,Ys,Zs).reverse([], []).reverse([H|T], R) :- reverse(T, S), append(S, [H], R).

Page 91: An introduction to Logic Programming

91

Meta-interpreter - version 3Pre-processing – Program transformation.

Every rule A :- B1, B2, ..., Bn in program P, is written in program P' as a fact rule(A,[B1, B2, ..., Bn]).

Program P': rule( member(X,[X|Xa]), [ ]).rule( member(X,[Y|Ys]), [member(X,Ys)]).rule( append([ ],Xs,Xs), [ ]).rule( append([X|Xs],Ys,[X|Zs]), [append(Xs,Ys,Zs)]).rule( reverse([], []), []).rule( reverse([H|T], R), [reverse(T, S), append(S, [H], R)]).

Page 92: An introduction to Logic Programming

92

Meta-interpreter - version 3% Signature: solve(Goal)/1% Purpose: % Goal is true if it is true when posed to the program P.solve(Goal) :- solve(Goal, []).

% Signature: solve(Goal, Rest_of_goals)/2solve([ ], [ ] ).solve([ ], [G| Goals] ) :- solve(G, Goals).solve([A|B], Goals):- append(B,Goals,Goals1),

solve(A,Goals1).solve(A, Goals) :- rule(A, B),

solve(B, Goals).

Page 93: An introduction to Logic Programming

93

Logic Programming SummaryPure(relational) LP: • typeless• atomic terms, atomic formula• program axioms, queries• lexical scoping, global definitions• unification, build proof tree (backtracking)• decidabilityFLP: • functors, composite terms• listsProlog: • cut!• meta-circular interpreters (clause, tuples/list)