Logic Programming

75
Logic Programming Logic Programming Nai-Wei Lin Department of Computer Science and Information Engineering National Chung Cheng University

description

Logic Programming. Nai-Wei Lin Department of Computer Science and Information Engineering National Chung Cheng University. Outline. An introduction to logic Predicate calculus Horn clauses Unification and resolution Basic Prolog programming Syntax of Prolog Control in Prolog - PowerPoint PPT Presentation

Transcript of Logic Programming

Page 1: Logic Programming

Logic ProgrammingLogic Programming

Nai-Wei LinDepartment of Computer Science and Information

EngineeringNational Chung Cheng

University

Page 2: Logic Programming

Outline• An introduction to logic

– Predicate calculus– Horn clauses– Unification and resolution

• Basic Prolog programming– Syntax of Prolog– Control in Prolog – Data structures in Prolog

• Advanced Prolog programming– Cut– Negation– Higher-order predicates– Incomplete data structures

Page 3: Logic Programming

Logic Programming

• Logic programming uses logic as a

programming language

• Logic programming computes relations

instead of functions

• Logic programming is declarative

programming

Page 4: Logic Programming

Relations and Functions

Let A and B be sets• A relation from A to B is a subset of A × B.• A function from A to B is a relation R from A to

B such that for each a A, there exists one and only one b B such that (a,b) R.

• Functions are special cases of relations.• Example: A = {a1, a2, a3, a4} B = {b1, b2, b3} R = {(a1,b1), (a2,b2), (a2,b3), (a4,b3)} F = {(a1,b1), (a2,b2), (a3,b3), (a4,b3)}

Page 5: Logic Programming

Propositions

1. Boolean values true and false are propositions.

2. A symbol is a proposition which has value

true or false.

3. If p and q are propositions, then so are (a) p: negation of p,(b) p q: conjunction of p and q,(c) p q: disjunction of p and q, and (d) p q: implication from p to q.

Page 6: Logic Programming

Predicates1. Each predicate denotes a relation among constants.2. Each predicate is defined as a set of terms.3. Terms are relation instances whose arguments can be

constants or existential quantified () or universal quantified () variables

Examples: parent(ted, derek). parent(ted, dena). parent(ted, dustin). parent(derek, adams). X,Y.(parent(X,Y) ancestor(X, Y)). X,Y.(Z.parent (X,Z) ancestor(Z,Y) ancestor(X,Y)).

Page 7: Logic Programming

Theorem Proving

• Predicates as axioms

• Queries as theorems

• Answering queries as proving theorems

Page 8: Logic Programming

An Example

parent(ted, derek).

parent(ted, dena).

parent(ted, dustin).

parent(derek, adams).

X,Y.(parent(X,Y) ancestor(X, Y)).

X,Y.( Z.parent(X, Z) ancestor(Z, Y) ancestor(X, Y)).

parent(ted, derek)?

X.parent(ted, X)?

X,Y.parent(X, Y)?

X.ancestor(ted, X)?

Page 9: Logic Programming

Resolution Inference Rule

• Predicates as axioms• Queries as theorems• Resolution as the inference rule

p, p q ┝ q• Proving theorems by backward deduction

Page 10: Logic Programming

Horn Clauses

• The set of Horn clauses is a subset of predicate calculus

• Each of the implication in the Horn clauses is in the form of p1 ,…, pn q where n 0

• Resolution inference rule can be efficiently used only for Horn clauses

Page 11: Logic Programming

A Notation for Horn Clauses

Facts (universal): <fact> ::= <term>. parent(ted, derek).

Rules (universal or existential): <rule>::= <term> :- <terms>. ancestor(X, Y) :- parent(X, Y). ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).

Queries (existential): <query> ::= ?- <terms>. ?- parent(ted, X). ?- ancestor(ted, X).

Page 12: Logic Programming

Clauses and Predicates

• A clause is a fact or a rule• A literal is a relation occurrence in a clause• Clause head is the literal before ‘ :- ’ in a clause• Clause body consists of the literals after ‘ :- ’ in a clause• A predicate is the set of clauses whose head has the same predicate symbol and arity (number of arguments)

Page 13: Logic Programming

An Example

parent(ted, derek).

parent(ted, dena).

parent(ted, dustin).

parent(derek, adams).

ancestor(X, Y) :- parent(X,Y).

ancestor(X, Y) :- parent(X, Z), ancestor(Z, Y).

Page 14: Logic Programming

Substitution• A substitution is a function from variables to terms {X → ted, Y → derek}

• Rules for applying a substitution σ to a term: 1. σ(X) = U, if X →U is in σ 2. σ(X) = X, otherwise 3. σ(f(T1,T2)) = f(U1,U2), if σ(T1) = U1, σ(T2) = U2

{X → ted, Y → derek}(X) = ted {X → ted, Y → derek}(Z) = Z {X → ted, Y → derek}(parent(X,Y)) = parent(ted,derek)

Page 15: Logic Programming

Instances

• A term U is an instance of a term T if U = σ(T) for some substitution σ

parent(ted,derek) is an instance of parent (X, derek)

parent(X,derek) is an instance of parent (X, Y)

Page 16: Logic Programming

Unification

• Terms T1 and T2 unify if σ(T1) = σ(T2) for some substitution σ

• Substitution σ is called a unifier of T1 and T2.

{H → a, T → b} (f(a , T))

= {H → a, T → b} (f(H, b))

= f(a, b)

Page 17: Logic Programming

Most General Unifier

• Substitution σ is the most general unifier of T1 and T2 if for all other unifiers σ’ , σ’ (T1) is an instance of σ(T1).

{X1 → a, X2 → Z, Y1 → a, Y2 → Z }(f(X1,X2,c))

= {X1 → a, X2 → Z, Y1 → a, Y2 → Z }(f(Y1,Y2,c))

= f(a, Z, c)

{X1 → a, X2 → b, Y1 → a, Y2 → b }(f(X1,X2,c))

= {X1 → a, X2 → b, Y1 → a, Y2 → b }(f(Y1,Y2,c))

= f(a, b, c)

{Z → b}(f(a, Z, c)) = f(a, b, c)

Page 18: Logic Programming

Resolution

Let

Qi = a1, a2, …, an

be a query and

b :- b1, b2, …, bm

be a rule.

If σis the most general unifier of a1 and b, and

Qi+1 = σ(b1, b2, …, bm, a2, …, an),

then we say Qi is reduced to Qi+1 via a resolution

step.

Page 19: Logic Programming

An Example

The most general unifier for the query

ancestor (X, adams)

and the rule

ancestor (X, Y) :- parent (X, Y)

is

σ = {Y → adams }

Hence, the query after the resolution of these two

is

σ(parent(X, Y)) = parent(X, adams)

Page 20: Logic Programming

Computation• A computation for a query Q with respect to a

set of predicates is a (possibly infinite) sequence of queries Q = Q0, …, Qi, Qi+1, …

such that each Qi is reduced to the query Qi+1

via a resolution step.

?- ancestor(X, adams). ?- parent(X, adams). true

σ = {Y → adams}

σ = {X → derek}

Page 21: Logic Programming

Computation

• If a computation C has an infinite sequence of queries, then C does not terminate.

• If a computation C with queries Q0, …, Qn

is maximal, and Qn = true, then C is said to succeed with answer substitution

n … 1

restricted to the variables occurring in Q0.• Otherwise, C is said to fail.

Page 22: Logic Programming

An Example• ?- ancestor (X, adams).

ancestor (X, Y) :- parent (X, Y).

σ1 = {Y → adams}

σ1(parent(X, Y)) = parent(X, adams)

?- parent(X, adams).• ?- parent (X, adams).

parent (derek,adams).

σ2 = {X → derek}

true σ = σ2 σ1 = {X → derek, Y → adams}

= {X → derek}

Page 23: Logic Programming

Prolog

• Prolog is a general programming language for

logic programming

• Prolog also includes some imperative

features for efficiency

• Prolog uses the same syntactic form for both

programs and data

Page 24: Logic Programming

Prolog

• The first Prolog system was developed in early 1970’s by Alain Colmerauer and his group at the University of Marseille-Aix as a specialized theorem prover for natural language processing.

• The first efficient Prolog was developed in late 1970’s by David Warren and his group in University of Edinburgh.

Page 25: Logic Programming

Prolog SyntaxTerms:

< term > ::= < number > | < variable >

| < symbol > | < symbol > (<terms>)

< terms > ::= < term > | < term > , < terms >

Examples: 1, 1994 N, N1, _, _1 ted, derek parent(X, Y) +(2, *(3, 4)), 2 + 3 * 4

Page 26: Logic Programming

A Typical Session?- consult( ‘family.pl’).yes

?- parent(ted,derek).yes

?- parent(ted,X).X = derek;X = dena;X= dustin;no

?- parent(ted, X).X = derekyes

return next solution

stop returning solutions

Page 27: Logic Programming

A Typical Session?- parent(X, Y).X = ted, Y = derek;X = ted, Y = dena;X = ted, Y = dustin;X = derek, Y = adams;no

?- ancestor(X, Y).X = ted, Y = derek;X = ted, Y = dena;X = ted, Y = dustin;X = derek, Y = adams;X = ted, Y = adams;no

?- halt.

Page 28: Logic Programming

Control in Prolog

• Try clauses from top to bottom

• Resolve literals from left to right

Page 29: Logic Programming

An Example

parent(ted, derek). parent(ted, dena).parent(ted, dustin).parent(derek, adams). ?- parent(ted,X).X = derek;X = dena;X = dustin;no

parent(ted,X).

σ1 = {X→derek}

true

σ2 = {X→dena}

true

σ3 = {X→dustin}

true

false

Page 30: Logic Programming

An Exampleparent (ted, derek).parent (derek, adams).ancestor(X, Y) :- parent(X, Y).ancestor(X, Y) :- parent (X, Z), ancestor (Z, Y).

?- ancestor (X, adams).

σ1 = {X → X_1, Y_1 → adams}

σ1(parent(X_1, Y_1)) = parent (X_1, adams) ?- parent (X_1, adams).

σ2 = {X_1 → derek}

σ = σ2 σ1 = {X → derek} X = derek; (succeed)

Page 31: Logic Programming

An Example

ancestor(X,adams).

σ1 = {X→X_1,Y_1→adams} σ1 = {X→X_1,Y_1→adams}

parent (X_1, adams).

σ2 = {X_1 → derek}

truefalse

parent(X_1, Z_1), ancestor(Z_1, adams)).

Page 32: Logic Programming

An Example?- ancestor(X, adams).

σ1 = {X X_1, Y_1 adams}

σ1(parent(X_1, Z_1), ancestor(Z_1, Y_1))

= parent(X_1, Z_1), ancestor(Z_1, adams))

?- parent(X_1, Z_1), ancestor(Z_1, adams).

σ2 = {X_1 ted, Z_1 derek}

σ2(ancestor(Z_1, adams)) = ancestor(derek, adams)

?- ancestor(derek, adams).

σ3 = {X_2 derek, Y_2 adams}

σ3(parent(X_2, Y_2)) = parent(derek, adams)

?- parent(derek, adams). σ4 = { }

σ = σ4 σ3 σ2 σ1

= {X,X_1ted, Y_1,Y_2adams, Z_1,X_2derek}

X = ted; (succeed)

Page 33: Logic Programming

An Example

parent(X_1, Z_1), ancestor(Z_1, adams).

σ2 = {X_1 ted, Z_1 derek}

ancestor(derek, adams).

truefalse

parent(derek, adams).

σ4 = { }

σ3 = {X_2 derek, Y_2 adams}

σ2 = {X_1 derek, Z_1 adams}

ancestor(adams, adams).

σ3 = {X_2 derek, Y_2 adams}

parent(derek, Z_2), ancestor(Z_2, adams).

Page 34: Logic Programming

An Example?- ancester(derek, adams).

σ3 = {X_2 derek,Y_2 adams}

σ3(parent(X_2, Z_2), ancestor(Z_2, Y_2)) = parent(derek, Z_2), ancestor(Z_2, adams)?- parent(derek, Z_2), ancestor(Z_2, adams).

σ4 = {Z_2 adams}

σ4(ancestor(Z_2, adams)) = ancestor(adams, adams)?- ancestor(adams, adams).

σ5 = {X_3adams,Y_3adams}

σ5(parent(X_3, Y_3)) = parent(adams, adams)?- parent(adams, adams).(fail)

Page 35: Logic Programming

An Example

parent(derek, Z_2), ancestor(Z_2, adams).

σ4 = {Z_2 adams}

ancestor(adams, adams).

false false

parent(adams, adams).σ5 = {X_3adams,Y_3adams}

false

σ5 = {X_3adams,Y_3adams}parent(adams, Z_3),ancestor(Z_3, adams).

Page 36: Logic Programming

An Example

?- ancestor(adams, adams).

σ5 = {X_3 adams,Y_3 adams}

σ5(parent(X_3, Z_3), ancestor(Z_3, Y_3))

= parent(adams, Z_3), ancestor(Z_3, adams)

?- parent(adams, Z_3), ancestor(Z_3, adams).

(fail)

parent(adams, Z_3), ancestor(Z_3, adams).

false false

Page 37: Logic Programming

An Example

?- parent(X_1, Z_1), ancestor(Z_1, adams).

σ2 = {X_1 derek, Z_1 adams}

σ2(ancestor(Z_1, adams)) = ancestor(adams, adams)

?- ancestor(adams, adams).

σ3 = {X_2 adams, Y_2 adams}

σ3(parent(X_2, Y_2)) = parent(adams, adams)

?- parent(adams, adams). (fail)

Page 38: Logic Programming

An Example

ancestor(adams, adams).

σ3 = {X_2 adams,Y_2 adams} σ3 = {X_2 adams,Y_2 adams}

parent (adams, adams).

falsefalse

parent(adams, Z_1), ancestor(Z_1, adams)).

falsefalse

Page 39: Logic Programming

An Example

?- ancestor(adams, adams).

σ3 = {X_2 adams, Y_2 adams}

σ3(parent(X_2, Z_2), ancestor(Z_2, Y_2)) = parent(adams, Z_2), ancestor(Z_2, adams)

?- parent(adams, Z_1), ancestor(Z_1, adams).

(fail)

Page 40: Logic Programming

Prolog Search Tree ancestor(X,adams) σ1 = {X→X_1,Y_1→adams}

parent(X_1,adams) parent(X_1,Z_1),ancestor(Z_1,adams) σ2 = {X_1→derek} σ2 = {X_1ted,Z_1derek} σ2 = {X_1derek,Z_1adams}

fail succeed ancestor(derek,adams) ancestor(adams,adams) X = derek σ3 = {X_2derek,Y_2adams}

parent(derek,adams) parent(derek,Z_2),ancestor(Z_2,adams) fail fail σ4 = { } σ4 = {Z_2 adams}

fail succeed fail ancestor(adams, adams) X = ted σ5 = {X_3adams,Y_3adams}

parent(adams,adams) parent(adams,Z_3),ancestor(Z_3,adams)

fail fail fail fail

Page 41: Logic Programming

Literal Order Affects Treesappend([ ], L, L).append([H|X ], Y, [ H|Z ]) :- append (X, Y, Z).prefix(X, Z) :- append (X, Y, Z).suffix (Y, Z) :- append (X, Y, Z).

?-suffix( [a], L), prefix (L, [a, b, c]).L = [a];-- non-terminating –

?-suffix ([a], L).L = [a];L = [_1, a];L = [_1, _2, a];…

Page 42: Logic Programming

Literal Order Affects Treessuffix ([a], L), prefix (L, [a, b, c])

append(X_1, [a], L), prefix (L, [a, b, c])

prefix([a], [a,b,c]) append(X_2, [a], Z_2), prefix([H_2|Z_2], [a, b, c])

append([a], Y_2, [a, b, c]) prefix([H_2|[a]], [a, b, c]) fail …

fail append([ ], Y_3, [b, c]) append([H_2|[a]], Y_3, [a, b, c])

succeed fail fail fail

Page 43: Logic Programming

Literal Order Affects Trees

suffix ([a], L), prefix (L, [a, b, c])

L = [a]

prefix([a], [a, b, c])

L = [_1,a]

prefix([_1,a], [a, b, c])

L = [_1,_2,a]

prefix([_1,_2,a], [a, b, c])

...

succeed

fail

fail

Page 44: Logic Programming

Literal Order Affects Trees

append([ ], L, L).append([H|X ], Y, [ H|Z ]) :- append (X, Y, Z).

prefix(X, Z) :- append (X, Y, Z).suffix (Y, Z) :- append (X, Y, Z).

?- prefix(L, [a, b, c]), suffix ([a], L).L = [a];no

Page 45: Logic Programming

Literal Order Affects Trees

prefix (L, [a, b, c]), suffix ([a], L)

append (L, Y_1, [a, b, c]), suffix ([a], L)

suffix([a], [ ]) append(X_2, Y_2, [b, c]), suffix ([a], [a|X_2])

append(X_3, [a], []) suffix([a], [a]) append(X_3, Y_3, [c]),

suffix ([a], [a,b|X_3])

fail fail append(X_4, [a], [a])

succeed fail fail …

Page 46: Logic Programming

Literal Order Affects Trees

prefix (L, [a, b, c]), suffix ([a], L)

L = [ ]

suffix([a], [ ])L = [a]

suffix([a], [a])

L = [a,b]

suffix ([a], [a,b])

succeed

fail

fail L = [a,b,c]

suffix ([a], [a,b,c])

fail

Page 47: Logic Programming

Clause Order Affects Searchappend([ ], L, L).append([H|X], Y, [H|Z]) :- append(X, Y, Z).append2([H|X], Y, [H|Z]) :- append2(X, Y, Z).append2([ ], L, L).

?- append(X, [a], Z).X = [ ], Z = [a];X = [_1 ], Z = [_1, a];X = [_1, _2 ], Z = [_1, _2, a];…

?- append2(X, [a], Z).-- non-terminating --

Page 48: Logic Programming

Clause Order Affects Search

append(X, [c], Z) append2(X, [c], Z)

succeed succeed append(X_1, [c], Z_1) append2(X_1, [c], Z_1)

succeed succeed append (X_2, [c], Z_2) append2(X_2, [c], Z_2)

Page 49: Logic Programming

Terms as DataFunction symbols (functors) represent data

Lists: []

[a, b, c] .(a, .(b, .(c, [] ))) .(H , T) [H | T] [a | [b, c ]] [a, b | [c]] [a, b, c | [] ]

Trees:leafnonleaf(leaf, leaf)nonleaf(leaf, nonleaf(leaf, leaf ))

Page 50: Logic Programming

An Exampleappend([ ], L, L).append([H|X], Y, [H|Z]) :- append (X, Y, Z).?- append([ ], [ ], R).R = [ ];no ?- append([ ], [a, b], R) .R = [a, b];no?- append ([a, b], [c, d], R).R = [a, b, c, d];no ?- append (X, Y, [a, b] ).X = [ ], Y = [a, b];X = [a], Y = [b];X = [a, b], Y = [ ];no

Page 51: Logic Programming

The Predicate ‘functor’

?- functor(f(a, b, g(Z)), F, N).

Z = _23, F = f, N = 3

?- functor(a+b, F, N).F = +, N = 2

?- functor([a, b, c], F, N).F = . , N = 2

?- functor(apple, F, N).F = apple, N = 0

?- functor([a, b, c], ’.’, 3).no

?- functor(X, F, 2).X = f(_23, _24)

Page 52: Logic Programming

The Predicate ‘arg’• The predicate arg must be used with its first two

arguments instantiated

?- arg(2, related(john, mother(jane)), X) .X = mother(jane)

?- arg(1, a+(b+c), X) .X = a

?- arg(2, [a, b, c], X) .X = [b, c]

?- arg(1, a+(b+c), b) .no

Page 53: Logic Programming

An Examplesubterm(Term, Term).subterm(Sub, Term) :-

not atomic(Term),functor(Term, F, N),subterm(N, Sub, Term).

subterm(N, Sub, Term) :-N > 1,N1 is N-1,subterm(N1, Sub, Term).

subterm(N, Sub, Term) :-arg(N, Term, Arg).subterm(Sub, Arg).

Page 54: Logic Programming

The Predicate ‘=..’

?- foo(a, b, c) =.. X.X = [foo, a, b, c]

?- [a, b, c] =.. L.L = [’.’, a, [b, c]]

?- (a+b) =.. L.L = [+, a, b]

?- (a+b) =.. [+, X, Y]X = a, Y=b

?- X =.. [a, b, c]X = a(b,c)

Page 55: Logic Programming

An Example

subterm(Term, Term).subterm(Sub, Term) :- not atomic(Term),

Term =.. [F|Args],subterm_list(Sub, Args) .

subterm_list(Sub, [Arg|Args]) :- subterm(Sub, Arg).subterm_list(Sub, [Arg|Args]) :- subterm_list(Sub, Args).

Page 56: Logic Programming

Type Predicates

?- var(X) .yes

?- nonvar(X) .no

?- integer(23) .yes

?- atom(apple) .yes

?- atom(23) .no

?- atomic(apple) .yes

?- atomic(23)yes

Page 57: Logic Programming

The Predicate ‘=’

?- X = X.true;no

?- X = f(a).X = f(a);no

?- f(x) = f(a).X = a;no

?- f(X, b) = f(a, Y) .X = a, Y = b;no

?- f(X, b) = g(a, Y) .no

Page 58: Logic Programming

The Predicate ‘is’

?- X = 2 + 3.X = 2 + 3

?- X is 2 + 3.X = 5

?- X is 2 + 3, X = 5.X = 5

?- X is 2 + 3, X = 2 + 3.no

Page 59: Logic Programming

Relation Operators

?- 2 =:= 3.no

?- 2 =\= 3.yes

?- 2 > 3.no

?- 2 >= 3.no

?- 2 < 3.yes

?- 2 =< 3.yes

Page 60: Logic Programming

• A cut prunes the unexplored part of a Prolog search tree that is created during the execution of the predicate containing the cut.

H1 :- …

… Hi-1 :- …

Hi :- L1,…,Lj,!,Lj+1,…,Lm

Hi+1 :- …

Hn :- …

Cut(!)

Page 61: Logic Programming

Cut(!)H

H1 ... Hi-1 Hi+1 ... HnL1... Lj, !, Lj+1 ... Lm

L2... Lj, !, Lj+1 ... Lm

Lj, !, Lj+1 ... Lm

!, Lj+1 ... Lm

Lj+1 ... Lm

Page 62: Logic Programming

An Exampleqsort([], []).qsort([First|L], R) :- part(First, L, Ls, Lg), qsort(Ls, Rs), qsort(Lg, Rg), append(Rs, [First|Rg], R).

part(F, [], [], []).part(F, [X|L], [X|R1], R2) :- X =< F, !, part(F, L, R1, R2).part(F, [X|L], R1, [X|R2]) :- X > F, part(F, L, R1, R2).

Page 63: Logic Programming

Accumulator

qsort(Xs, Ys) :- qsort_tr(Xs, [], Ys).

qsort_tr([], Xs, Xs).

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

part(X, Xs, S, L),

qsort_tr(L, Ys, Ys1),

qsort_tr(S, [X|Ys1], Zs).

Page 64: Logic Programming

An Exampleperm([], []).perm(L, [R|Rs]) :- select(R, L, Ls), perm(Ls, Rs).select(X, [X|Xs], Xs).select(X, [Y|Ys], [Y|Zs]) :- select(X, Ys, Zs).

?- perm([a, b], R).R = [a, b];R = [b, a];no

?- select(R, [a, b], Ls) .R = a, Ls = [b];R = b, Ls = [a];no

Page 65: Logic Programming

Negation

• Logical negation: I can prove that it is false.

• First-order predicate calculus is undecidable: proving something true can always terminate, but proving something false may be non-terminating.

• Negation as failure: If I cannot prove that it is true, it must be false.

Page 66: Logic Programming

The Operator ‘not’

unmarried_student(X) :- student(X), not married(X).student(bill).married(joe).

?- unmarried_student(X).X = bill;no

Page 67: Logic Programming

The Implementation of ‘not’

not(X) :- X, !, fail.

not(_) .

Page 68: Logic Programming

Higher-Order Predicates

setof:

parent(ted, derek).parent(ted, dena).parent(derek, adams).

children(X, Kids) :- setof(C, parent(X,C), Kids).

?- children(ted, Kids).kids = [derek, dena];no

Page 69: Logic Programming

Higher-Order Predicatesbagof:

dept(ec, cs).dept(ec, ee).prof(cs, ted).prof(cs, derek).prof(ee, dena).prof(ee, ted).col_prof(C, P) :- dept(C, D), prof(D, P).col_profs(C, Ps) :- bagof(P, col_prof(C, P), Ps).

?- col_profs(ec, Ps).Ps = [ted, derek, dana, ted];no

Page 70: Logic Programming

Incomplete Data Structures

• The difference between two lists As and Bs can be denoted as a structure As\Bs, called a difference list.

• For example, [1, 2, 3|Xs]\Xs is the most general difference list representing the sequence 1, 2, 3, where [1, 2, 3|Xs] is the head and Xs the tail of the difference list.

Page 71: Logic Programming

Incomplete Data Structures

• Difference lists can lead to more concise and efficient programs.

• Two incomplete difference lists can be concatenated to give a third difference list in constant time. append_dl(Xs\Ys, Ys\Zs, Xs\Zs). ?- append_dl([a,b,c|Xs]\Xs,[1,2]\[],Ys). Xs = [1,2], Ys = [a,b,c,1,2]\[]

Page 72: Logic Programming

Difference Lists

qsort(Xs, Ys) :- qsort_dl(Xs, Ys\[ ]).qsort_dl([ ], Xs\Xs).qsort_dl([X|Xs], Ys\Zs) :-part(X, Xs, S, L),qsort_dl(S, Ys\[X|Ys1]), qsort_dl(L, Ys1\Zs).

qsort(Xs, Ys) :- qsort_dl(Xs, Ys, [ ]).qsort_dl([ ], Xs, Xs).qsort_dl([X|Xs], Ys, Zs) :-part(X, Xs, S, L),qsort_dl(S, Ys, [X|Ys1]), qsort_dl(L, Ys1, Zs).

Page 73: Logic Programming

Difference Listsqsort([5,7,3], Ys) qsort_dl([5,7,3], Ys\[ ]) part(5, [7,3], S1, L1) S1 = [3], L1 = [7] qsort_dl([3], Ys\[5|Ys1]) part(3, [ ], S2, L2) S2 = [ ], L2 = [ ] qsort_dl([ ], Ys\[3|Ys2]) Ys = [3|Ys2] qsort_dl([ ], Ys2\[5|Ys1]) Ys2 = [5|Ys1] qsort_dl([7], Ys1\[ ]) part(7, [ ], S3, L3) S3 = [ ], L3 = [ ] qsort_dl([ ], Ys1\[7|Ys3]) Ys1 = [7|Ys3] qsort_dl([ ], Ys3\[ ]) Ys3 = [ ]

Ys = [3,5,7]

Page 74: Logic Programming

Dictionaries

lookup(Key, [(Key,Value)|Dict], Value).lookup(Key,[(Key1,Value1)|Dict], Value) :-

Key =\= Key1, lookup(Key, Dict, Value).

Dict = [(ted,3301),(derek,3302)|Xs] ?- lookup(derek, Dict, N).

N = 3302 ?- lookup(dena, Dict, 3303). Dict = [(ted,3301),(derek,3302),(dena,3303)|Xs1]

Page 75: Logic Programming

Summary

• Logic programming uses logic as a

programming language and is declarative.

• Logic programming computes relations

instead of functions.

• Logic programming uses unification to

achieve bidirectional parameter passing

and to make use of incomplete data

structures.