172
1 AI 08226 Prolog (PRO gramming in LOG ic) Dr Darryl N. Davis Dr Darryl N. Davis Department of Computer Science Department of Computer Science University of Hull University of Hull

AI 08226 Prolog (PROgramming in LOGic)

Embed Size (px)

Citation preview

Page 1: AI 08226 Prolog (PROgramming in LOGic)

1

AI 08226

Prolog

(PROgramming in LOGic)

Dr Darryl N. DavisDr Darryl N. Davis

Department of Computer ScienceDepartment of Computer Science

University of HullUniversity of Hull

Page 2: AI 08226 Prolog (PROgramming in LOGic)

2

Bibliography

�� Prolog Programming for AI, Ivan Prolog Programming for AI, Ivan BratkoBratko, ,

��3/e, Addison3/e, Addison--Wesley, 2001.Wesley, 2001.

�� The Art of Prolog, Sterling, L. and Shapiro, E.,The Art of Prolog, Sterling, L. and Shapiro, E.,

��MIT Press, 1986. MIT Press, 1986.

�� Mastering Prolog, Rob LucasMastering Prolog, Rob Lucas

��UCL Press; ISBN: 1857284003, 1996. UCL Press; ISBN: 1857284003, 1996.

�� Programming in PROLOG, W.F. Programming in PROLOG, W.F. ClocksinClocksin, C.S. , C.S. MellishMellish

��SpringerSpringer--VerlagVerlag, ISBN: 3540583505, 1994. , ISBN: 3540583505, 1994.

�� PROLOG for Students, David H. PROLOG for Students, David H. CallearCallear,,

��LettsLetts Educational Ltd; ISBN: 1858050936, 1994. Educational Ltd; ISBN: 1858050936, 1994.

Page 3: AI 08226 Prolog (PROgramming in LOGic)

3

Introduction

�� Prolog is a declarative languageProlog is a declarative language

�� It is not procedural or objectIt is not procedural or object--basedbased

��But can build objects in itBut can build objects in it

�� Prolog works in terms of pattern instantiationProlog works in terms of pattern instantiation

�� Prolog does not have global variablesProlog does not have global variables

��Other than predicate (or Other than predicate (or functorfunctor) names) names

�� Programs typically built from facts and rulesPrograms typically built from facts and rules

��a fact is a bodiless rulea fact is a bodiless rule

�� its_sunny.its_sunny.

��weather(sunny).weather(sunny).

Page 4: AI 08226 Prolog (PROgramming in LOGic)

4

Prolog

�� Programs built from predicatesPrograms built from predicates

��which have the value which have the value truetrue or or fail (fail (akaaka false)false)

�� Prolog makes use ofProlog makes use of Closed World AssumptionClosed World Assumption

�� If predicate name exists and cannot match to it If predicate name exists and cannot match to it

�� then predicate assumed to be false.then predicate assumed to be false.

�� Prolog concerned with relationships between Prolog concerned with relationships between

objects and the truth of theseobjects and the truth of these

�� Prolog programming concernedProlog programming concerned

��with defining relations with defining relations

��and querying relationsand querying relations

Page 5: AI 08226 Prolog (PROgramming in LOGic)

5

Predicates and Functors

�� Prolog predicates called Prolog predicates called functorsfunctors

�� the name of the predicate, the name of the predicate, costcost(robot, 2000)(robot, 2000)

�� functorfunctor names are alphanames are alpha--numeric numeric

�� begin with lowercase alphabegin with lowercase alpha

�� testtest, , relationrelation, , test123test123, , relation1Arelation1A are acceptableare acceptable

��TestTest, , 123123, , TESTTEST, , !!££$$ are not acceptableare not acceptable

��Typically predicates relate set of objectsTypically predicates relate set of objects

�� color(robot, green).color(robot, green).

�� cost(robot, affordable).cost(robot, affordable).

��Predicates have 0, 1, 2, 3, etc. argumentsPredicates have 0, 1, 2, 3, etc. arguments

�� cost. cost.

�� cost(doshcost(dosh).). cost(spaceship, expensive).cost(spaceship, expensive).

Page 6: AI 08226 Prolog (PROgramming in LOGic)

6

Predicate Functors and Arity

�� Predicates have Predicates have functorfunctor and and arityarity

��No space between predicate name & first parenthesisNo space between predicate name & first parenthesis

��%color(1)%color(1)

��color(red).color(red).

��color(green).color(green).

��%color/2%color/2

��color(robot, red).color(robot, red).

��color(grass, green).color(grass, green).

��%color/3%color/3

��color(robot, red, shiny).color(robot, red, shiny).

��color(sea, green, dull).color(sea, green, dull).

Page 7: AI 08226 Prolog (PROgramming in LOGic)

7

Terms and variables

�� NO such thing as GLOBAL variableNO such thing as GLOBAL variable

��nearest is set of predicates as nearest is set of predicates as functor/arityfunctor/arity

combinationscombinations

�� Terms beginning with Uppercase Alpha Terms beginning with Uppercase Alpha

characters are variablescharacters are variables�� cost(Thing, X, Y).cost(Thing, X, Y).

�� Tokens starting with lower case characters are Tokens starting with lower case characters are

not.not.�� cost(robot, X, Y).cost(robot, X, Y).

�� cost(amigabotcost(amigabot, X, Y)., X, Y).

Page 8: AI 08226 Prolog (PROgramming in LOGic)

8

Use of Prolog

�� Calling prologCalling prolog

��click on the click on the plwinplwin icon in icon in WindowsNTWindowsNT

��on on unix/solarisunix/solaris use pl (or prolog)use pl (or prolog)

�� Loading a fileLoading a file

��consult(Filename).consult(Filename).

�� If all prolog have .pl extensions can doIf all prolog have .pl extensions can do

��??-- consult(myfileconsult(myfile). OR ?). OR ?-- [[myfilemyfile].].

�� If notIf not

��??-- consult(consult(‘‘mybizrrefile.txtmybizrrefile.txt’’).).

�� Exiting prologExiting prolog

��^d or halt.^d or halt.

Page 9: AI 08226 Prolog (PROgramming in LOGic)

9

Hints

�� Which prologWhich prolog

��available for free from module available for free from module webpageswebpages

�� Use the DOT <CR> to finish prolog sequenceUse the DOT <CR> to finish prolog sequence

��does not work otherwise!does not work otherwise!

�� Use the SEMIUse the SEMI--COLON for multiple answersCOLON for multiple answers

��when using the interpreterwhen using the interpreter

�� use halt. to prologuse halt. to prolog

��also ^dalso ^d

�� interrupting programsinterrupting programs

��use ^cuse ^c

Page 10: AI 08226 Prolog (PROgramming in LOGic)

10Online Help (html manual available)

�� help(<TERM>)help(<TERM>)

��??-- help(atom).help(atom).

�� atom(+Term)atom(+Term)

�� Succeeds if Term is bound to an atom.Succeeds if Term is bound to an atom.

�� apropos(<TERM>)apropos(<TERM>)

��??-- apropos(atom).apropos(atom).

�� atom/1 Type check for an atomatom/1 Type check for an atom

�� atomic/1 Type check for primitiveatomic/1 Type check for primitive

�� explain(<TERM>)explain(<TERM>)

��??-- explain(help).explain(help).

�� "help" is an atom"help" is an atom

��Referenced from 1Referenced from 1--th clause of online_help:help/0th clause of online_help:help/0

Page 11: AI 08226 Prolog (PROgramming in LOGic)

11

Use Comments in Code

�� Use Comments to document your codeUse Comments to document your code

�� Two formsTwo forms

��% Percent Sign % Percent Sign -- all to right is commentall to right is comment

�� /* In/* In--between these delimiters is a comment */between these delimiters is a comment */

�� For example:For example:

�� /* File : /* File : comments.plcomments.pl */*/

�� /* Author: D.N.Davis *//* Author: D.N.Davis */

�� /* 11:19 AM 11/* 11:19 AM 11--SeptSept--2002 */2002 */

�� /* AI 08226 Example for Prolog Lectures *//* AI 08226 Example for Prolog Lectures */

��% go/0 % go/0 -- predicate to start the program, it stops Prologpredicate to start the program, it stops Prolog

��go:go:-- halt.halt.

Page 12: AI 08226 Prolog (PROgramming in LOGic)

12Prolog-AI-L2 (From Here)�� L1 L1 –– Prolog basics and interpreterProlog basics and interpreter

�� L2 L2 –– Writing Prolog Code (Getting it do things)Writing Prolog Code (Getting it do things)

Page 13: AI 08226 Prolog (PROgramming in LOGic)

13

Prolog Syntax�� ConstantConstant

�� Integer:Integer: 0, 42, 0, 42, --1717

��Real:Real: 1.07, 1.07, --0.029, 917.10.029, 917.1

��Atoms:Atoms: wine, x, x1wine, x, x1

�� ‘‘FredFred’’, , ‘‘file.plfile.pl’’

�� not not ““fredfred”” -- that is a list [102, 114, 101, 100] that is a list [102, 114, 101, 100]

�� Variable:Variable:

�� initial upper caseinitial upper case X, Value, V12a, X, Value, V12a, UniqueToClauseUniqueToClause

�� initial underscoreinitial underscore _result, _2_result, _2

��anonymousanonymous __

Page 14: AI 08226 Prolog (PROgramming in LOGic)

14

Assignment and testing on numbers�� X is 22+1.X is 22+1.

X = 23 X = 23

�� ??-- X is X+1.X is X+1.

ERROR: Arguments are not sufficiently instantiatedERROR: Arguments are not sufficiently instantiated

�� ??-- X = X+1.X = X+1.

X = ... +... +1+1+1+1+1+1+1+1+1 X = ... +... +1+1+1+1+1+1+1+1+1

�� ??-- X = X = 1.X = X = 1.

ERROR: Syntax error: Operator priority clashERROR: Syntax error: Operator priority clash

ERROR: X =ERROR: X =

ERROR: ** here **ERROR: ** here **

ERROR: X = 1 . ERROR: X = 1 .

Page 15: AI 08226 Prolog (PROgramming in LOGic)

15

Prolog Syntax�� OperatorsOperators

��many built in binary and unary operatorsmany built in binary and unary operators

��Arithmetic Infix Arithmetic Infix { /, *, { /, *, --, +, // , mod}, +, // , mod}

�� ??-- A is 3+4*7.A is 3+4*7.

��A = 31A = 31

��Arithmetic Prefix (unary)Arithmetic Prefix (unary) {truncate, floor, round}{truncate, floor, round}

�� ??-- A is round( 34/31). A is round( 34/31).

��A = 1 A = 1

��Cannot use variable name for more than one valueCannot use variable name for more than one value

�� ??-- A is 3*5, A is A*5, A is A is 3*5, A is A*5, A is sqrt(Asqrt(A).).

�� Need to use differently named variablesNeed to use differently named variables

�� ??-- A1 is 3*5, A2 is A1*5, A3 is sqrt(A2).A1 is 3*5, A2 is A1*5, A3 is sqrt(A2).

Page 16: AI 08226 Prolog (PROgramming in LOGic)

16

Prolog Syntax - Facts

�� Relation Relation -- a predicate with a predicate with functorfunctor and and arityarity

��university/0university/0

�� university.university.

��cycle/1cycle/1

�� cycle(cycle(‘‘Not StartedNot Started’’).).

�� cycle(1).cycle(1).

�� thing/2thing/2

�� thing(agent1, agent).thing(agent1, agent).

�� ting(object1, obstacle).ting(object1, obstacle).

��distance/3distance/3

�� distance(agent1, object1, 10).distance(agent1, object1, 10).

�� distance(agent1, agent2, 15).distance(agent1, agent2, 15).

Page 17: AI 08226 Prolog (PROgramming in LOGic)

17

Example Facts – greek.pl

�� male(cronusmale(cronus).).male(zeusmale(zeus).). male(hadesmale(hades).).

�� male(aresmale(ares).). male(hermesmale(hermes).). male(apollomale(apollo).).

�� female(herafemale(hera).). female(maiafemale(maia).). female(letofemale(leto).).

�� female(artemisfemale(artemis).). female(irisfemale(iris).).

�� parent(cronusparent(cronus, , zeuszeus).). parent(cronusparent(cronus, , hadeshades).).

�� parent(zeusparent(zeus, , aresares).). parent(zeusparent(zeus, , hermeshermes).).

�� parent(zeusparent(zeus, , apolloapollo).). parent(zeusparent(zeus, , artemisartemis).).

�� parent(zeusparent(zeus, iris)., iris). parent(heraparent(hera, , aresares).).

�� parent(heraparent(hera, iris)., iris). parent(letoparent(leto, , apolloapollo).).

�� parent(letoparent(leto, , artemisartemis).). parent(maiaparent(maia, , hermeshermes).).

Page 18: AI 08226 Prolog (PROgramming in LOGic)

18

Loading Files into SWI-Prolog�� ??-- [[greekgreek].].

�� % d:/Teaching/AI/Code/GREEK.PL compiled 0.00 sec, 2,336 bytes% d:/Teaching/AI/Code/GREEK.PL compiled 0.00 sec, 2,336 bytes

�� % Accessing the data% Accessing the data

�� ??-- listing(malelisting(male).).

�� ??-- listing(femalelisting(female).).

�� ??-- listing(parentlisting(parent).).

�� ??-- male(Amale(A).).

�� 2 ?2 ?-- male(Amale(A).).

�� A = A = cronuscronus

�� 3?3?-- female(Afemale(A).).

�� A = hera ;A = hera ;

�� A = maia ;A = maia ;

�� A = leto ;A = leto ;

�� A = artemis ;A = artemis ;

�� A = iris ;A = iris ;

�� NoNo

Page 19: AI 08226 Prolog (PROgramming in LOGic)

19

More on the use of not

�� female(athenefemale(athene).). male(hermesmale(hermes).).

�� not(male(X)).not(male(X)).

�� not(female(X)).not(female(X)).

�� not(male(X)), not(female(X)).not(male(X)), not(female(X)).

�� not( (male(X) , female(X) ) ).not( (male(X) , female(X) ) ).

�� male(X) , female(X).male(X) , female(X).

�� not( (male(X) ; female(X) ) ).not( (male(X) ; female(X) ) ).

�� male(X) ; female(X).male(X) ; female(X).

�� % now add% now add

�� female(hermaphrodite). male(hermaphrodite).female(hermaphrodite). male(hermaphrodite).

Page 20: AI 08226 Prolog (PROgramming in LOGic)

20

Negation of Facts�� Logic Unary (Infix)Logic Unary (Infix)

�� not/1, not/1, not(predicatenot(predicate).).

�� If predicate known then negation can be doneIf predicate known then negation can be done�� not(male(hermesnot(male(hermes)).)). NoNo

�� not(female(hermesnot(female(hermes)).)). YesYes

�� If predicate not known then negation is an errorIf predicate not known then negation is an error�� not(greek(hermesnot(greek(hermes)).)). Fail Fail –– greek/1 undefinedgreek/1 undefined

�� Can use not to surround more than one clause BUTCan use not to surround more than one clause BUT……�� ??-- not( not( male(hermesmale(hermes), ), female(hermesfemale(hermes)).)).

�� ERROR: Undefined procedure: not/2ERROR: Undefined procedure: not/2

�� ERROR: However, there are definitions for:ERROR: However, there are definitions for:

�� ERROR: not/1ERROR: not/1

�� NoNo

�� 3 ?3 ?-- not( ( not( ( male(hermesmale(hermes), ), female(hermesfemale(hermes) ) ).) ) ).

�� YesYes

Page 21: AI 08226 Prolog (PROgramming in LOGic)

21

Prolog and logic (in later lectures)

�� Prolog based on first order predicate calculusProlog based on first order predicate calculus

��constants, variables, compound terms,constants, variables, compound terms,

��not ( not ( ¬¬ ), and ( ), and ( ∧∧ ), or ( ), or ( ∨∨ ), ),

�� implies ( implies ( ⇐⇐ ) (( ) (( ⇒⇒ )), equivalence ()), equivalence (⇔⇔ ))

�� for all (for all (∀∀∀∀∀∀∀∀ ), there exists (), there exists (∃∃∃∃∃∃∃∃ ))

�� ∃∃∃∃∃∃∃∃ •• woman(y) woman(y) ∧∧ parent(y, x) parent(y, x)

⇐⇐ ∀∀x x •• man(x) man(x) ∧∧ ¬¬(x = ash)(x = ash)

�� ∃∃∃∃∃∃∃∃ •• woman(y) woman(y) ∧∧ parent(y, x) parent(y, x)

⇐⇐ ∀∀x x •• woman(x) woman(x) ∧∧ ¬¬(x = elm)(x = elm)

Page 22: AI 08226 Prolog (PROgramming in LOGic)

22

Clauses and Programs

�� Unit ClauseUnit Clause

��constant or relation terminated with a constant or relation terminated with a fullstopfullstop

�� toolkit_initialisedtoolkit_initialised..

�� perceives(agent1, [agent2, object1]).perceives(agent1, [agent2, object1]).

�� knows(agent1, nothing).knows(agent1, nothing).

�� NonNon--unit Clauseunit Clause

��constructed from constants and relations using, binary constructed from constants and relations using, binary

operators, operators, ““::--”” ““,,””

�� knows(A, B):knows(A, B):-- perceives(A, B).perceives(A, B).

�� agent( A ) :agent( A ) :-- thing( A, agent ).thing( A, agent ).

�� perceived( A ) :perceived( A ) :-- perceives( _wildcard, A).perceives( _wildcard, A).

Page 23: AI 08226 Prolog (PROgramming in LOGic)

23

The use of the Semi-colon - or

�� Alternative matchesAlternative matches

�� state(wet):state(wet):--

�� (fell_in_the_sea(fell_in_the_sea ;; raining_heavily).raining_heavily).

��On many occasions this becomes unclearOn many occasions this becomes unclear

��with more complex clauseswith more complex clauses

��Alternatively produce multiple clauses (preferable)Alternatively produce multiple clauses (preferable)

�� state(wet):state(wet):--

�� fell_in_the_sea.fell_in_the_sea.

�� state(wet):state(wet):--

�� raining_heavily.raining_heavily.

Page 24: AI 08226 Prolog (PROgramming in LOGic)

24Predicates: Multiple Instances Allowed

�� Unit Clauses (Facts) Unit Clauses (Facts) % male/1% male/1

male(apollomale(apollo).).

male(zeusmale(zeus).).

�� NonNon--Unit Clauses (Rules) Unit Clauses (Rules) % sibling/2% sibling/2

sibling(Xsibling(X, Y):, Y):--

father(Zfather(Z, X),, X),

father(Zfather(Z, Y)., Y).

sibling(Xsibling(X, Y):, Y):--

mother(Zmother(Z, X),, X),

mother(Zmother(Z, Y)., Y).

Page 25: AI 08226 Prolog (PROgramming in LOGic)

25

Prolog programs

�� Consist of clauses of facts, rules and questionsConsist of clauses of facts, rules and questions

��Facts (unit clauses)Facts (unit clauses)

�� thing(agent1, agent).thing(agent1, agent).

�� agent(agent2, static, up, 55, 67).agent(agent2, static, up, 55, 67).

��Rules (nonRules (non--unit clauses)unit clauses)

�� agent(Name) :agent(Name) :-- thing(Name, agent).thing(Name, agent).

�� agent(Nameagent(Name):):-- agent(Nameagent(Name, _state, _direction, _x, _y)., _state, _direction, _x, _y).

��Questions (via the interpreter or other code)Questions (via the interpreter or other code)

�� ??-- agent(A).agent(A).

�� A is agent1.A is agent1.

�� Yes.Yes.

�� A relation is specified by facts and rulesA relation is specified by facts and rules

�� A procedure is set of clauses about the same relationA procedure is set of clauses about the same relation

Page 26: AI 08226 Prolog (PROgramming in LOGic)

26

Example Prolog File: program1.pl��% An example about agent and objects% An example about agent and objects

�� thing(agent1, agent). thing(agent2, agent).thing(agent1, agent). thing(agent2, agent).

�� thing(object1, object). thing(object1, object).

�� location(agent1, 10, 10). location(agent2, 15, 35).location(agent1, 10, 10). location(agent2, 15, 35).

�� location(object1, 10, 30).location(object1, 10, 30).

��% Distance/3 evaluates distance between things% Distance/3 evaluates distance between things

��distance(Thing1, Thing2, Distance):distance(Thing1, Thing2, Distance):--

location(Thing1, X1, Y1),location(Thing1, X1, Y1),

location(Thing2, X2, Y2),location(Thing2, X2, Y2),

XdiffXdiff is X1is X1--X2, X2, XsqXsq is is XdiffXdiff**XdiffXdiff,,

YdiffYdiff is Y1is Y1--Y2, Y2, YsqYsq is is YdiffYdiff**YdiffYdiff,,

Distance is Distance is sqrt(Xdiff+Ydiffsqrt(Xdiff+Ydiff).).

Page 27: AI 08226 Prolog (PROgramming in LOGic)

27

Querying the program in swi-prolog% PROGRAM1.PL compiled 0.00 sec, 4,700 bytes% PROGRAM1.PL compiled 0.00 sec, 4,700 bytes

??-- distance(agent1, agent2, X).distance(agent1, agent2, X).

X = 25.4951 X = 25.4951

??-- distance(A,B,0).distance(A,B,0).

A = agent1A = agent1

B = agent1 B = agent1

??-- distance(A,B,C).distance(A,B,C).

A = agent1A = agent1

B = agent1B = agent1

C = 0 ;C = 0 ;

A = agent1A = agent1

B = agent2B = agent2

C = 25.4951 ;C = 25.4951 ;

etc.etc.

Page 28: AI 08226 Prolog (PROgramming in LOGic)

28

Hints about Debug

�� ^c results in the help prompt^c results in the help prompt

��Action (h for help) ?Action (h for help) ?

��Typing an 'h' gets us:Typing an 'h' gets us:

�� a: abort a: abort b: breakb: break

�� c: continue c: continue e: e:

�� g: goals g: goals t: tracet: trace

�� 'e' s the program immediately'e' s the program immediately

�� 'a' aborts whatever you've type so far'a' aborts whatever you've type so far

�� 'c' continues where you left off'c' continues where you left off

�� 'h' gets us the 'Action' help menu, again'h' gets us the 'Action' help menu, again

Page 29: AI 08226 Prolog (PROgramming in LOGic)

29

Program Execution

�� Prolog tries to satisfy goals (questions) byProlog tries to satisfy goals (questions) by

��Matching the head of a ruleMatching the head of a rule

��Satisfying the body of the ruleSatisfying the body of the rule

�� (unification is from left to right)(unification is from left to right)

•• success success →→

��Head :Head :-- TermTerm11, Term, Term22, , ……, , TermTermnn..

•• ←← failurefailure

�� If a specific instance of a term fails, If a specific instance of a term fails,

�� Prolog looks for another instance to matchProlog looks for another instance to match

�� If a term fails, Prolog backtracks andIf a term fails, Prolog backtracks and

�� attempts to reattempts to re--evaluate previous terms.evaluate previous terms.

�� If a rule failsIf a rule fails

�� Prolog tries to find another matching head (in sequence)Prolog tries to find another matching head (in sequence)

Page 30: AI 08226 Prolog (PROgramming in LOGic)

30

Example Prolog Execution 0

�� % example prolog database using fact/2 % example prolog database using fact/2

�� fact(grass, green).fact(grass, green).

�� fact(sky, blue).fact(sky, blue).

�� fact(sun, yellow).fact(sun, yellow).

�� fact(sea, green).fact(sea, green).

�� fact(desert, yellow).fact(desert, yellow).

�� % example rules using rule/1% example rules using rule/1

�� rule(X):rule(X):-- fact(X, Color), fact(Y, Color), X fact(X, Color), fact(Y, Color), X \\= Y.= Y.

�� rule(X):rule(X):-- fact(T1, X), fact(T2, X), T1 fact(T1, X), fact(T2, X), T1 \\= T2.= T2.

Page 31: AI 08226 Prolog (PROgramming in LOGic)

31Example Prolog Execution I�� ??-- rule(A). rule(A).

��Matches against first instance of rule/1Matches against first instance of rule/1

��AA unified to unified to XX

��Look to first term of body i.e.Look to first term of body i.e. fact(X, Color),fact(X, Color),

��matches to first instance of fact/2matches to first instance of fact/2

��XX unified to unified to grassgrass, , ColorColor unified to unified to greengreen

��Look to second term of body i.e. Look to second term of body i.e. fact(Y, Color),fact(Y, Color),

��Color Color is instantiated to is instantiated to greengreen from first termfrom first term

��matches to first instance of fact/2matches to first instance of fact/2

��YY unified to unified to grassgrass

��Look to third term of body, i.e. Look to third term of body, i.e. X X \\= Y.= Y.

�� both both XX and and YY unified to unified to grassgrass, it fails, it fails

�� backtracks to retry second termbacktracks to retry second term

Page 32: AI 08226 Prolog (PROgramming in LOGic)

32Example Prolog Execution II

��Rematch second term of body i.e. Rematch second term of body i.e. fact(Y, Color),fact(Y, Color),

��ColorColor is instantiated to is instantiated to greengreen from first termfrom first term

�� tries to match serially to fact/2tries to match serially to fact/2

��matches to fourth instance of fact/2matches to fourth instance of fact/2

��YY unified to unified to seasea

��Look to third term of body, i.e. Look to third term of body, i.e. X X \\= Y.= Y.

��XX unified to unified to grassgrass, , YY unified to unified to seasea

�� these are different so comparison succeedsthese are different so comparison succeeds

��Body now fully instantiatedBody now fully instantiated

��X = grassX = grass

��At this point can press return or type in At this point can press return or type in ““;;””

�� if latter now looks for further matchesif latter now looks for further matches

Page 33: AI 08226 Prolog (PROgramming in LOGic)

33

Example Prolog Execution III

��Look to first term of body i.e.Look to first term of body i.e. fact(X, Color),fact(X, Color),

�� looks to second instance of fact/2looks to second instance of fact/2

��XX unified to unified to skysky, , ColorColor unified to unified to blueblue

��Look to second term of body i.e. Look to second term of body i.e. fact(Y, Color),fact(Y, Color),

��ColorColor is instantiated to is instantiated to blueblue from first termfrom first term

��matches to second instance of fact/2matches to second instance of fact/2

��YY unified to unified to skysky

��Look to third term of body, i.e. Look to third term of body, i.e. X X \\= Y.= Y.

�� both both XX and and YY unified to unified to skysky, it fails, it fails

�� backtracks to retry second termbacktracks to retry second term

��Cannot find another match to Cannot find another match to fact(VAR, blue)fact(VAR, blue)

�� backtracks to retry first termbacktracks to retry first term

Page 34: AI 08226 Prolog (PROgramming in LOGic)

34Example Prolog Execution IV

��Look to first term of body i.e.Look to first term of body i.e. fact(X, Color),fact(X, Color),

�� looks to third instance of fact/2looks to third instance of fact/2

��XX unified to sun, unified to sun, ColorColor unified to unified to yellowyellow

��Look to second term of body i.e. Look to second term of body i.e. fact(Y, Color),fact(Y, Color),

��ColorColor is instantiated to is instantiated to yellowyellow from first termfrom first term

��matches to fifth instance of fact/2matches to fifth instance of fact/2

��YY unified to unified to desertdesert

��Look to third term of body, i.e. Look to third term of body, i.e. X X \\= Y.= Y.

��XX unified to unified to sunsun, and , and YY unified to unified to desertdesert, it succeeds, it succeeds

��Body now fully instantiatedBody now fully instantiated

��X = sunX = sun

��At this point can press return or type in At this point can press return or type in ““;;””

�� if latter now looks for further matchesif latter now looks for further matches

Page 35: AI 08226 Prolog (PROgramming in LOGic)

35Example Prolog Execution V��Look to first term of body i.e.Look to first term of body i.e. fact(X, Color),fact(X, Color),

�� looks to fourth instance of fact/2looks to fourth instance of fact/2

��XX unified to unified to seasea, , ColorColor unified to unified to greengreen

��Look to second term of body i.e. Look to second term of body i.e. fact(Y, Color),fact(Y, Color),

��ColorColor is instantiated to is instantiated to greengreen from first termfrom first term

��matches to first instance of fact/2matches to first instance of fact/2

��YY unified to unified to grassgrass

��Look to third term of body, i.e. Look to third term of body, i.e. X X \\= Y.= Y.

��XX unified to unified to seasea and and YY unified to unified to grassgrass, it succeeds, it succeeds

��Body now fully instantiatedBody now fully instantiated

��X = seaX = sea

��At this point can press return or type in At this point can press return or type in ““;;””

�� if latter now looks for further matchesif latter now looks for further matches

Page 36: AI 08226 Prolog (PROgramming in LOGic)

36

Full Set of Results:�� d:SEA.PL compiled, 0.11 sec, 1,328 bytes.d:SEA.PL compiled, 0.11 sec, 1,328 bytes.

�� ??-- rule(X).rule(X).

�� X = grass ;X = grass ; % rule/1 (1)% rule/1 (1)

�� X = sun ;X = sun ; % rule/1 (1)% rule/1 (1)

�� X = sea ;X = sea ; % rule/1 (1)% rule/1 (1)

�� X = desert ;X = desert ; % rule/1 (1)% rule/1 (1)

�� X = green ;X = green ; % rule/1 (2)% rule/1 (2)

�� X = yellow ;X = yellow ; % rule/1 (2)% rule/1 (2)

�� X = green ;X = green ; % rule/1 (2)% rule/1 (2)

�� X = yellow ;X = yellow ; % rule/1 (2)% rule/1 (2)

�� NoNo % exhausted possibilities% exhausted possibilities

�� ??--

Page 37: AI 08226 Prolog (PROgramming in LOGic)

37

On Prolog Execution

�� Prolog explores choices in orderProlog explores choices in order

��backtracking ensures that all possibilities are triedbacktracking ensures that all possibilities are tried

�� if necessaryif necessary

�� Backtracking is an activity under control of Backtracking is an activity under control of

Prolog not the programmerProlog not the programmer

��Programmer can force backtracking or stop itProgrammer can force backtracking or stop it

��using repeat, fail, true and ! (cut) operatorsusing repeat, fail, true and ! (cut) operators

�� covered in later lecturescovered in later lectures

�� Prolog has no global variablesProlog has no global variables

��Scope of a variable is a clauseScope of a variable is a clause

Page 38: AI 08226 Prolog (PROgramming in LOGic)

38

Pictures of program execution

�� Trees can be used to represent space Trees can be used to represent space

��of possible solutions to a goalof possible solutions to a goal

�� Consider:Consider:

fact(grassfact(grass, green)., green).

fact(skyfact(sky, blue)., blue).

fact(seafact(sea, green)., green).

�� % example rules using rule/1% example rules using rule/1

rule(Xrule(X):):-- fact(Xfact(X, Color), , Color), fact(Yfact(Y, Color), , Color), not(Xnot(X == Y).== Y).

�� with the goal with the goal

??-- rule(Arule(A).).

Page 39: AI 08226 Prolog (PROgramming in LOGic)

39

Tree1

rule(A)

fact(Xfact(X, Color), , Color), fact(Yfact(Y, , Color),not(XColor),not(X==Y).==Y).

fact(grass, green),

fact(grass,green),

not(grass==grass)

This path fails - try another

Page 40: AI 08226 Prolog (PROgramming in LOGic)

40

Tree2

This path fails too!

fact(Xfact(X, Color), , Color), fact(Yfact(Y, , Color),not(XColor),not(X==Y).==Y).

fact(grass, green),

fact(grass,green),

not(grass==grass)

fact(grass, green),

fact(sky,blue),

not(X==Y)

fact(grassfact(grass, green), , green), fact(Yfact(Y, , green),not(grassgreen),not(grass==Y).==Y).

Page 41: AI 08226 Prolog (PROgramming in LOGic)

41

Tree3 – first of the succeeds

Many other paths, some succeed, most fail!

rule(A)

fact(Xfact(X, Color), , Color), fact(Yfact(Y, , Color),not(XColor),not(X==Y).==Y).

fact(grass, green),

fact(grass,green),

not(grass==grass)

fact(grass, green),

fact(sky,blue),

not(X==Y)

fact(grass, green),

fact(sea, green),

not(grass==sea)

fact(grassfact(grass, green), , green), fact(Yfact(Y, , green),not(grassgreen),not(grass==Y).==Y).

Page 42: AI 08226 Prolog (PROgramming in LOGic)

42

Agents in a Discrete World: See CWK

Page 43: AI 08226 Prolog (PROgramming in LOGic)

43

Modelling Automata

�� A Finite State Machine has a logical structureA Finite State Machine has a logical structure

��Can be used for Very Simple AgentsCan be used for Very Simple Agents

�� Defined on its input and internal stateDefined on its input and internal state

��InputInput: : SpaceFreeSpaceFree | | SpaceBlockSpaceBlock

��State: AKSF | AKSB | StaticState: AKSF | AKSB | Static

��Output: Output: Nothing|TurnLeft|MoveAheadNothing|TurnLeft|MoveAhead

��StateChangeFunctionStateChangeFunction : :

Input+InternalInput+Internal→→InternalInternal

��OutputFunctionOutputFunction : :

Input+Internal Input+Internal →→OutputOutput

Page 44: AI 08226 Prolog (PROgramming in LOGic)

44

Specification of FSM as Table

Input State Change Output

SpaceFree AKSF AKSF Ahead

SpaceFree AKSB AKSF Ahead

SpaceFree Static AKSF Nothing

SpaceBlock AKSF AKSB Nothing

SpaceBlock AKSB AKSB TurnLeft

SpaceBlock Static AKSB Nothing

Page 45: AI 08226 Prolog (PROgramming in LOGic)

45

FSM as prolog - state change function

%statechange/3%statechange/3

% % statechange(inputstatechange(input, state, , state, newstatenewstate).).

statechange(spacefree,aksf,aksfstatechange(spacefree,aksf,aksf).).

statechange(spacefree,aksb,aksfstatechange(spacefree,aksb,aksf).).

statechange(spacefree,static,aksfstatechange(spacefree,static,aksf).).

statechange(spaceblock,aksf,aksbstatechange(spaceblock,aksf,aksb).).

statechange(spaceblock,aksbstatechange(spaceblock,aksb, , aksbaksb).).

statechange(spaceblock,static,aksbstatechange(spaceblock,static,aksb).).

�� % many alternative codes% many alternative codes

Page 46: AI 08226 Prolog (PROgramming in LOGic)

46

FSM as prolog - output function

% output/3% output/3

% output(input, state, output).% output(input, state, output).

output(spacefree,aksf,aheadoutput(spacefree,aksf,ahead).).

output(spacefree,aksb,aheadoutput(spacefree,aksb,ahead).).

output(spacefree,static,nothingoutput(spacefree,static,nothing).).

output(spaceblock,aksf,nothingoutput(spaceblock,aksf,nothing).).

output(spaceblock,aksboutput(spaceblock,aksb, , turnleftturnleft).).

output(spaceblock,static,nothingoutput(spaceblock,static,nothing).).

�� % many alternative codes% many alternative codes

Page 47: AI 08226 Prolog (PROgramming in LOGic)

47

THE Full FSM in prolog : fsm1.pl

% fsm/4% fsm/4

% % fsm(inputfsm(input, state, , state, newstatenewstate, output)., output).

% defined over % defined over statechangestatechange and outputand output

fsm(Inputfsm(Input, State, , State, NewStateNewState, Output):, Output):--

statechange(Inputstatechange(Input, State, , State, NewStateNewState),),

output(Input, output(Input, NewStateNewState, Output)., Output).

??-- [fsm1].[fsm1].

% FSM1.PL compiled 0.00 sec, 1,812 bytes% FSM1.PL compiled 0.00 sec, 1,812 bytes

??-- fsm(A,B,C,Dfsm(A,B,C,D).).

A = A = spacefreespacefree B = B = aksfaksf C = C = aksfaksf D = aheadD = ahead

Page 48: AI 08226 Prolog (PROgramming in LOGic)

48

Clause Order

�� Matching determines which clauses can be used to Matching determines which clauses can be used to

solve a goalsolve a goal

�� Clauses tried in orderClauses tried in order

��sequentially in consulted ordersequentially in consulted order

�� left to right in bodiesleft to right in bodies

�� If progress halts, backtracking is triedIf progress halts, backtracking is tried

�� Matching (clause instantiation) is depthMatching (clause instantiation) is depth--first first

search through prolog clausessearch through prolog clauses

Page 49: AI 08226 Prolog (PROgramming in LOGic)

49

Matching

�� General rules for matching two terms S and T;General rules for matching two terms S and T;

�� If S and T are constantsIf S and T are constants

�� Then they match only if they are the same entityThen they match only if they are the same entity

��??-- 2 == 2.2 == 2.

��YesYes

��??-- a = a.a = a.

��YesYes

��??-- 'Term1' == 'Term2'.'Term1' == 'Term2'.

��NoNo

��??-- "String1" = "String1"."String1" = "String1".

��YesYes

Page 50: AI 08226 Prolog (PROgramming in LOGic)

50

Matching

�� General rules for matching two terms S and T;General rules for matching two terms S and T;

�� If S is a variable and T is anythingIf S is a variable and T is anything

�� Then they match.Then they match.

��??-- S = _var.S = _var.

�� S = _G147 S = _G147

�� YesYes

��??-- S= _.S= _.

�� S = _G123 S = _G123

�� YesYes

��??-- S = a.S = a.

�� S = a S = a

�� YesYes

Page 51: AI 08226 Prolog (PROgramming in LOGic)

51

Matching of Variables

�� Order of clauses mattersOrder of clauses matters

��??-- A = B, A = 1, B = 1.A = B, A = 1, B = 1.

�� YesYes

��??-- A = 1, B = 1, A = B.A = 1, B = 1, A = B.

�� YesYes

��??-- A = 1, B = 1, A == B.A = 1, B = 1, A == B.

�� YesYes

��??-- A == B, A = 1, B = 1.A == B, A = 1, B = 1.

�� NoNo

��? A = B, A == B.? A = B, A == B.

�� YesYes

��So? So? ??-- A == B, A = B. ?A == B, A = B. ?-- A = B, A == B.A = B, A == B.

Page 52: AI 08226 Prolog (PROgramming in LOGic)

52

Matching

�� General rules for matching two terms S and T;General rules for matching two terms S and T;

�� If S and T are clauses then they match only if If S and T are clauses then they match only if

�� S and T have the same principal S and T have the same principal functorfunctor andand

�� all their corresponding components match.all their corresponding components match.

��??-- date(D, M, 2001) = date(D1, date(D, M, 2001) = date(D1, januaryjanuary, Y1)., Y1).

�� D = _G339D = _G339

�� M = M = januaryjanuary

�� D1 = _G339D1 = _G339

�� Y1 = 2001 Y1 = 2001

�� YesYes

��??-- date(D, M, 2001) = date(D1, date(D, M, 2001) = date(D1, januaryjanuary, 2020)., 2020).

�� NoNo

Page 53: AI 08226 Prolog (PROgramming in LOGic)

53

Matching

�� Matching in prolog always results in the most Matching in prolog always results in the most

general instantiationgeneral instantiation

��committing variables to the least possible extentcommitting variables to the least possible extent

��??-- date(D, M, 2001) = date(D1, date(D, M, 2001) = date(D1, januaryjanuary, Y1),, Y1),

�� date(D, M, 2001) = date(1, M, Y).date(D, M, 2001) = date(1, M, Y).

�� InstantiationsInstantiations

��First GoalFirst Goal Second GoalSecond Goal Third GoalThird Goal

�� D = D1D = D1 D = 1D = 1 D = 1, D1 = 1D = 1, D1 = 1

�� M = M = januaryjanuary M = MM = M M = M = januaryjanuary

�� Y1 = 2001Y1 = 2001 Y = 2001Y = 2001 Y1 = 2000, Y = 2001Y1 = 2000, Y = 2001

��Consecutive goals leading to more specific valuesConsecutive goals leading to more specific values

Page 54: AI 08226 Prolog (PROgramming in LOGic)

54

Unification

�� Position in unification is the same as in matchingPosition in unification is the same as in matching

�� two atoms unify if they are equaltwo atoms unify if they are equal

��one variable and one atomone variable and one atom

�� the variable is instantiated to the value of the atomthe variable is instantiated to the value of the atom

��structures unify if:structures unify if:

�� they have the same they have the same functorfunctor

�� they have the same number of componentsthey have the same number of components

�� corresponding components unifycorresponding components unify

��E.g. p(X, b) and p(a, Y) unify with {a/X, b/Y}E.g. p(X, b) and p(a, Y) unify with {a/X, b/Y}

�� p(X, X) and p(a, b) do not unifyp(X, X) and p(a, b) do not unify

�� p(X, f(Y) and p(Y, f(a)) unify with {a/X, a/Y}p(X, f(Y) and p(Y, f(a)) unify with {a/X, a/Y}

Page 55: AI 08226 Prolog (PROgramming in LOGic)

55

Unification & The occurs check

�� Unification is indeterminate for two componentsUnification is indeterminate for two components

�� IF one being a variable and another being a termIF one being a variable and another being a term

�� if the variable appears in the termif the variable appears in the term

�� occurs(X):occurs(X):-- p(X) = p(f(X)).p(X) = p(f(X)).

��X = f(f(f(f(f(f(f(f(f(f(...)))))))))) X = f(f(f(f(f(f(f(f(f(f(...))))))))))

�� MatchingMatching: :

�� a process that determines whether a clause can be a process that determines whether a clause can be

used to solve goal.used to solve goal.

��Many prologs do not include occurs checksMany prologs do not include occurs checks

�� If two terms unify they matchIf two terms unify they match

�� If two terms match, they may not unify.If two terms match, they may not unify.

Page 56: AI 08226 Prolog (PROgramming in LOGic)

56

Exploiting matching

�� Achieve computation by clause application, Achieve computation by clause application,

selection and constructionselection and construction

summary(item(book,

author(pratchett),

title(the_colour_of_magic),

code(124753)),

book(pratchett, the_color_of_magic) ).

opus(O):-

summary(item(book,author(_A), title(_T),code(_)), O).

?- opus(O).

O = book(pratchett, the_color_of_magic)

Page 57: AI 08226 Prolog (PROgramming in LOGic)

57

Testing data

�� valid(day, Day):valid(day, Day):--

�� Day > 0, Day < 32.Day > 0, Day < 32.

�� valid(month, Month):valid(month, Month):--

�� Month > 0, Month < 13.Month > 0, Month < 13.

�� ??-- valid(day, 0).valid(day, 0). nono

�� ??-- valid(month, 0).valid(month, 0). nono

�� ??-- valid(day, 29).valid(day, 29). yesyes

�� ??-- valid(month, 11).valid(month, 11). yesyes

�� ??-- valid(day, 32).valid(day, 32). nono

�� ??-- valid(month, 13).valid(month, 13). nono

Page 58: AI 08226 Prolog (PROgramming in LOGic)

58

Procedural programming - I/O�� write(Text) and write(Text) and nlnl

��outputs text (wrapped in single apostrophes)outputs text (wrapped in single apostrophes)

�� ??-- write(write(‘‘Hi Hi -- some meaningless textsome meaningless text’’).).

��??-- write(write(‘‘Yet some more textYet some more text’’), nl.), nl.

��careful with the apostrophes, I.e. do not writecareful with the apostrophes, I.e. do not write

��write(write(‘‘FredaFreda’’ss piece of textpiece of text’’).).

�� read(Term) read(Term) -- reads a term from the input.reads a term from the input.

��??-- read(Term).read(Term).

�� |: a.|: a.

��Term = a Term = a

��YesYes

Page 59: AI 08226 Prolog (PROgramming in LOGic)

59

Example :Month Conversion program�� go:go:-- write(write(‘‘Integers to Names of MonthsIntegers to Names of Months’’), ), nlnl,,

�� write(write(‘‘Enter the month as an integer: Enter the month as an integer: ‘‘),),

�� read(Month),read(Month),

�� write(write(‘‘The month is The month is ‘‘),),

�� month(Month), month(Month), nlnl..

�� month(1):month(1):-- write(write(‘‘JanuaryJanuary’’).).

�� month(2):month(2):-- write(write(‘‘FebuaryFebuary’’).).

�� month(12):month(12):-- write(write(‘‘DecemberDecember’’).).

�� month(_):month(_):-- write(write(‘‘Unknown Unknown -- Incorrect EntryIncorrect Entry’’).).

Page 60: AI 08226 Prolog (PROgramming in LOGic)

60�� ??-- go.go.

�� Integers to Names of MonthsIntegers to Names of Months

�� Enter the month as an integer: 9.Enter the month as an integer: 9.

�� The month is SeptemberThe month is September

�� ??-- go.go.

�� Integers to Names of MonthsIntegers to Names of Months

�� Enter the month as an integer: Enter the month as an integer: --1.1.

�� The month is Unknown The month is Unknown -- Incorrect EntryIncorrect Entry

�� ??-- go.go.

�� Integers to Names of MonthsIntegers to Names of Months

�� Enter the month as an integer: a.Enter the month as an integer: a.

�� The month is Unknown The month is Unknown -- Incorrect EntryIncorrect Entry

Page 61: AI 08226 Prolog (PROgramming in LOGic)

61

Arithmetic Program�� run:run:-- get_a_number(Num1),get_a_number(Num1),

�� get_a_number(Num2), get_a_number(Num2), nlnl,,

�� write(write(‘‘a : Add.a : Add.’’), ), nlnl,,

�� write(write(‘‘b: Subtract.b: Subtract.’’), ), nlnl,,

�� write(write(‘‘c: Multiply.c: Multiply.’’), ), nlnl,,

�� write(write(‘‘d: Divide.d: Divide.’’), ), nlnl,,

�� write(write(‘‘e: .e: .’’), ), nlnl,,

�� write(write(‘‘Your choice: Your choice: ‘‘), read(Choice), ), read(Choice), nlnl,,

�� choice(Num1, Num2, Choice), choice(Num1, Num2, Choice), nlnl..

�� get_a_number(N):get_a_number(N):-- write(write(‘‘Enter a number: Enter a number: ‘‘),),

�� read(N).read(N).

Page 62: AI 08226 Prolog (PROgramming in LOGic)

62�� % choice/3 % choice/3 -- now perform what was asked with checksnow perform what was asked with checks

�� choice(_,N1, N2):choice(_,N1, N2):--

�� ( not(number(N1)); not(number(N2))),( not(number(N1)); not(number(N2))),

�� write('Numbers not entered when asked'), write('Numbers not entered when asked'), nlnl..

�� choice(a, N1, N2):choice(a, N1, N2):-- X is N1+N2,X is N1+N2,

�� write('Answer = '), write(X), write('Answer = '), write(X), nlnl..

�� choice(b,N1, N2):choice(b,N1, N2):-- X is N1X is N1--N2,N2,

�� write('Answer = '), write(X), write('Answer = '), write(X), nlnl..

�� choice(c,N1, N2):choice(c,N1, N2):-- X is N1*N2,X is N1*N2,

�� write('Answer = '), write(X), write('Answer = '), write(X), nlnl..

�� choice(d,N1, N2):choice(d,N1, N2):-- X is N1/N2,X is N1/N2,

�� write('Answer = '), write(X), write('Answer = '), write(X), nlnl..

�� choice(e,_,_):choice(e,_,_):-- halt.halt.

�� choice(_,_,_):choice(_,_,_):-- write('Strange Values Entered'), write('Strange Values Entered'), nlnl..

Page 63: AI 08226 Prolog (PROgramming in LOGic)

63

Unacceptable Prolog!�� The following will not be accepted by PrologThe following will not be accepted by Prolog

�� run:run:-- Total = 0,Total = 0,

�� write(write(‘‘Enter a number: Enter a number: ‘‘), ), read(Numread(Num),),

�� Total is Total + Num,Total is Total + Num,

�� write(write(‘‘Enter another number: Enter another number: ‘‘), ), read(Numread(Num ),),

�� Total is Total + Num ,Total is Total + Num ,

�� write(write(‘‘Total is Total is ‘‘), write(Total ), ), write(Total ), nlnl..

� A major difference between declarative and procedural

programming languages

� While subgoals may appear like instructions

�� They remain goals with unification & matching rulesThey remain goals with unification & matching rules

�� ieie variable names can be used once in a callvariable names can be used once in a call

Page 64: AI 08226 Prolog (PROgramming in LOGic)

64

Programming Techniques : Recursion

Programming Techniques : RecursionProgramming Techniques : Recursion

�� In procedural languagesIn procedural languages

��recursion is a procedure or subroutine calling itselfrecursion is a procedure or subroutine calling itself

�� In PrologIn Prolog

��recursion involves a rule calling itself as a recursion involves a rule calling itself as a subgoalsubgoal

�� Example:Example:

�� loop:- write(‘This is a loop’), loop.loop:- write(‘This is a loop’), loop.

�� Problem : how does this stop?Problem : how does this stop?

�� Many ways of doing this in PrologMany ways of doing this in Prolog

Programming Techniques : RecursionProgramming Techniques : Recursion

�� In procedural languagesIn procedural languages

��recursion is a procedure or subroutine calling itselfrecursion is a procedure or subroutine calling itself

�� In PrologIn Prolog

��recursion involves a rule calling itself as a recursion involves a rule calling itself as a subgoalsubgoal

�� Example:Example:

�� loop:- write(‘This is a loop’), loop.loop:- write(‘This is a loop’), loop.

�� Problem : how does this stop?Problem : how does this stop?

�� Many ways of doing this in PrologMany ways of doing this in Prolog

Programming Techniques : RecursionProgramming Techniques : Recursion

�� In procedural languagesIn procedural languages

��recursion is a procedure or subroutine calling itselfrecursion is a procedure or subroutine calling itself

�� In PrologIn Prolog

��recursion involves a rule calling itself as a recursion involves a rule calling itself as a subgoalsubgoal

�� Example:Example:

�� loop:- write(‘This is a loop’), loop.loop:- write(‘This is a loop’), loop.

�� Problem : how does this stop?Problem : how does this stop?

�� Many ways of doing this in PrologMany ways of doing this in Prolog

Programming Techniques : RecursionProgramming Techniques : Recursion

�� In procedural languagesIn procedural languages

��recursion is a procedure or subroutine calling itselfrecursion is a procedure or subroutine calling itself

�� In PrologIn Prolog

��recursion involves a rule calling itself as a recursion involves a rule calling itself as a subgoalsubgoal

�� Example:Example:

�� loop:- write(‘This is a loop’), loop.loop:- write(‘This is a loop’), loop.

�� Problem : how does this stop?Problem : how does this stop?

�� Many ways of doing this in PrologMany ways of doing this in Prolog

Programming Techniques : RecursionProgramming Techniques : Recursion

�� In procedural languagesIn procedural languages

��recursion is a procedure or subroutine calling itselfrecursion is a procedure or subroutine calling itself

�� In PrologIn Prolog

��recursion involves a rule calling itself as a recursion involves a rule calling itself as a subgoalsubgoal

�� Example:Example:

�� loop:- write(‘This is a loop’), loop.loop:- write(‘This is a loop’), loop.

�� Problem : how does this stop?Problem : how does this stop?

�� Many ways of doing this in PrologMany ways of doing this in Prolog

Programming Techniques : RecursionProgramming Techniques : Recursion

�� In procedural languagesIn procedural languages

��recursion is a procedure or subroutine calling itselfrecursion is a procedure or subroutine calling itself

�� In PrologIn Prolog

��recursion involves a rule calling itself as a recursion involves a rule calling itself as a subgoalsubgoal

�� Example:Example:

�� loop:- write(‘This is a loop’), loop.loop:- write(‘This is a loop’), loop.

�� Problem : how does this stop?Problem : how does this stop?

�� Many ways of doing this in PrologMany ways of doing this in Prolog

Programming Techniques : RecursionProgramming Techniques : Recursion

�� In procedural languagesIn procedural languages

��recursion is a procedure or subroutine calling itselfrecursion is a procedure or subroutine calling itself

�� In PrologIn Prolog

��recursion involves a rule calling itself as a recursion involves a rule calling itself as a subgoalsubgoal

�� Example:Example:

�� loop:- write(‘This is a loop’), loop.loop:- write(‘This is a loop’), loop.

�� Problem : how does this stop?Problem : how does this stop?

�� Many ways of doing this in PrologMany ways of doing this in Prolog

Page 65: AI 08226 Prolog (PROgramming in LOGic)

65

Programming Techniques : Recursion

�� In procedural languagesIn procedural languages

�� recursion is a procedure or subroutine calling itselfrecursion is a procedure or subroutine calling itself

�� In PrologIn Prolog

�� recursion involves a rule calling itself as a recursion involves a rule calling itself as a subgoalsubgoal

�� Example:Example:

�� loop:loop:-- write(write(‘‘This is a loopThis is a loop’’), loop.), loop.

�� Problem : how does this stop?Problem : how does this stop?

�� Many ways of doing this in PrologMany ways of doing this in Prolog

Page 66: AI 08226 Prolog (PROgramming in LOGic)

66

Conditional Recursion�� loop :loop :-- write(write(‘‘TYPE end TO ENDTYPE end TO END’’), read(Word),), read(Word),

�� ( Word = end; loop).( Word = end; loop).

�� This is equivalent to a REPEAT This is equivalent to a REPEAT …… UNTIL loop.UNTIL loop.

�� Usual way in Prolog is to place terminating Usual way in Prolog is to place terminating

condition before recursive loopcondition before recursive loop

��Called Head RecursionCalled Head Recursion

�� loop(end).loop(end).

�� loop(_):loop(_):-- write(write(‘‘Type end to END: Type end to END: ‘‘),),

�� read(Word), loop(Word).read(Word), loop(Word).

�� Equivalent to a WHILE Equivalent to a WHILE …… DO DO

�� terminating condition tested at start of the loopterminating condition tested at start of the loop

Page 67: AI 08226 Prolog (PROgramming in LOGic)

67

Prolog So Far�� L1 L1 –– Prolog basics and interpreterProlog basics and interpreter

�� L2 L2 –– Atoms, Numbers, Arithmetic, Clause TypesAtoms, Numbers, Arithmetic, Clause Types

�� L3 L3 –– Programs, Matching and ExecutionPrograms, Matching and Execution

�� L4 L4 –– ModellingModelling Finite State Automata, MatchingFinite State Automata, Matching

�� L5 L5 –– Unification, Numbers, Testing, ProceduralUnification, Numbers, Testing, Procedural

�� L6 L6 –– Recursion and ListsRecursion and Lists

Page 68: AI 08226 Prolog (PROgramming in LOGic)

68Counted Recursion*�� % Bad Style making use of % Bad Style making use of ““;;””

�� loop(Nloop(N):):-- write(write(‘‘The value of N is: The value of N is: ‘‘),),

�� write(N), write(N), nlnl, M is N, M is N--1, (M = 0; loop(M)).1, (M = 0; loop(M)).

�� % Preferred Style% Preferred Style

�� loop(0).loop(0).

�� loop(N):loop(N):--write(write(‘‘The value of N is: The value of N is: ‘‘),),

�� write(N), write(N), nlnl, M is N, M is N--1, 1, loop(Mloop(M).).

�� % With extra checks on value of N% With extra checks on value of N

�� loop(0).loop(0).

�� loop(N):loop(N):-- N > N > --1,1,

�� write(write(‘‘The value of N is: The value of N is: ‘‘),),

�� write(N), write(N), nlnl, ,

�� M is NM is N--1, loop(M).1, loop(M).

�� loop(Xloop(X):):-- write(write(‘‘LoopLoop Error Error –– Undefined Undefined ArgArg: : ‘‘), ),

�� write*X), write*X), nlnl..

Page 69: AI 08226 Prolog (PROgramming in LOGic)

69

Example of Recursion*�� factorial(1, 1).factorial(1, 1).

�� factorial(N, Factorial):factorial(N, Factorial):-- M is NM is N--1,1,

�� factorial(M, Factorial1),factorial(M, Factorial1),

�� Factorial is Factorial1*N.Factorial is Factorial1*N.

�� ??-- trace, factorial(3,F).trace, factorial(3,F).

�� factorial(3, _G352) , _L146 is 3factorial(3, _G352) , _L146 is 3--1 ?, 2 is 31 ?, 2 is 3--1 ?1 ?

�� factorial(2, _L147) ?, _L159 is 2factorial(2, _L147) ?, _L159 is 2--1 ?, 1 is 21 ?, 1 is 2--1 ?1 ?

�� factorial(1, _L160) ? factorial(1, 1) ?factorial(1, _L160) ? factorial(1, 1) ?

�� _L147 is 1*2 ?, 2 is 1*2 ?, factorial(2, 2) ?, _L147 is 1*2 ?, 2 is 1*2 ?, factorial(2, 2) ?,

�� _G352 is 2*3 ?, 6 is 2*3 ?, factorial(3, 6) ?,_G352 is 2*3 ?, 6 is 2*3 ?, factorial(3, 6) ?,

�� F = 6 F = 6

Page 70: AI 08226 Prolog (PROgramming in LOGic)

70�� power2(0, 1).power2(0, 1).

�� power2(N, Result):power2(N, Result):-- M is NM is N--1,1,

�� power2(M, power2(M, PartialResPartialRes),),

�� Result is Result is PartialResPartialRes*2.*2.

�� ??-- trace, power2(3,R).trace, power2(3,R).

�� power2(3, _G208) ? power2(3, _G208) ? _L133 is 3_L133 is 3--1 ? 2 is 31 ? 2 is 3--1 ?1 ?

�� power2(2, _L134) ?power2(2, _L134) ? _L146 is 2_L146 is 2--1 ? 1 is 21 ? 1 is 2--1 ?1 ?

�� power2(1, _L147) ? power2(1, _L147) ? _L159 is 1_L159 is 1--1 ? 0 is 11 ? 0 is 1--1 ?1 ?

�� power2(0, _L160) ?power2(0, _L160) ? power2(0, 1) ?power2(0, 1) ?

�� _L147 is 1*2 ?_L147 is 1*2 ? 2 is 1*2 ?2 is 1*2 ? power2(1, 2) ?power2(1, 2) ?

�� _L134 is 2*2 ?_L134 is 2*2 ? 4 is 2*2 ? 4 is 2*2 ? power2(2, 4) ?power2(2, 4) ?

�� _G208 is 4*2 ?_G208 is 4*2 ? 8 is 4*2 ?8 is 4*2 ? power2(3, 8) ?power2(3, 8) ?

�� R = 8 R = 8

Page 71: AI 08226 Prolog (PROgramming in LOGic)

71

Lists in Prolog*

�� List: an ordered sequence of elements List: an ordered sequence of elements (of any length)(of any length)

�� Elements of a list can be:Elements of a list can be:

��constants: integer, real, atomconstants: integer, real, atom

��variablesvariables

�� factsfacts

��other listsother lists

�� rulesrules

�� Elements of a list are enclosed in square bracketsElements of a list are enclosed in square brackets

�� [1, 2, 3][1, 2, 3] [a, b, c, d][a, b, c, d]

�� [peach, pear, plum][peach, pear, plum] [peach, 2, b, [3, 5, 7, 9]][peach, 2, b, [3, 5, 7, 9]]

�� [ ][ ] % the empty list% the empty list

Page 72: AI 08226 Prolog (PROgramming in LOGic)

72

Lists, characters and “strings”

�� note:note:

��??-- A = A = ““A StringA String””. .

�� A = [65, 32, 83, 116, 114, 105, 110, 103] A = [65, 32, 83, 116, 114, 105, 110, 103]

�� YesYes

�� name/2name/2

��a standard Prolog predicate that converts atoms into a standard Prolog predicate that converts atoms into

lists of ASCII characters and vicelists of ASCII characters and vice--versaversa

��Remember when using this that Atom is not an atomRemember when using this that Atom is not an atom

��But But ‘‘AtomAtom’’ isis

��As is atom, As is atom, aTomaTom, , aTOMaTOM etc.etc.

Page 73: AI 08226 Prolog (PROgramming in LOGic)

73

Lists, characters and “strings”

�� ??-- name(mrRustyname(mrRusty, A)., A).

�� A = [109, 114, 82, 117, 115, 116, 121] A = [109, 114, 82, 117, 115, 116, 121]

�� ??-- name(Atom, [82, 117, 115, 116, 121]).name(Atom, [82, 117, 115, 116, 121]).

�� Atom = 'Rusty' Atom = 'Rusty'

�� ??-- name('Atom', A).name('Atom', A).

�� A = [65, 116, 111, 109] A = [65, 116, 111, 109]

�� ??-- name(atom, A).name(atom, A).

�� A = [97, 116, 111, 109] A = [97, 116, 111, 109]

�� ??-- name(Atom,[]).name(Atom,[]).

�� Atom = ''Atom = ''

Page 74: AI 08226 Prolog (PROgramming in LOGic)

74

Handling Lists*�� Lists are manipulated by separating the Head from the TailLists are manipulated by separating the Head from the Tail

�� [Head | Tail ][Head | Tail ]

�� [1 | [2, 3, 4, 5] ][1 | [2, 3, 4, 5] ]

�� [a | [b, c, d] ][a | [b, c, d] ]

�� [pear | [peach, plum] ][pear | [peach, plum] ]

�� The [ H | T] notation can be used to build new listsThe [ H | T] notation can be used to build new lists

�� ??-- Z = [ a, b, c, d, e], Z = [H|T].Z = [ a, b, c, d, e], Z = [H|T].

�� Z = [a, b, c, d, e], H is a, T is [b, c, d, e]Z = [a, b, c, d, e], H is a, T is [b, c, d, e]

�� ??-- Z = [a, b, c, d], X is [1 | Z]Z = [a, b, c, d], X is [1 | Z]

�� X = [1, a, b, c, d ]X = [1, a, b, c, d ]

Page 75: AI 08226 Prolog (PROgramming in LOGic)

75

Handling Lists*

�� The [Head | Tail ] notation can be used to separate The [Head | Tail ] notation can be used to separate

the first few elements of a list from the Tailthe first few elements of a list from the Tail

�� [First, Second | Tail ][First, Second | Tail ]

�� [1, 2 | [3, 4, 5] ][1, 2 | [3, 4, 5] ]

�� [a, b | [c, d] ][a, b | [c, d] ]

�� [pear, peach | [plum] ][pear, peach | [plum] ]

�� [ a, b, c | [] ][ a, b, c | [] ]

��??-- [ F, S | Tail ] = [ a, b, c, d, e].[ F, S | Tail ] = [ a, b, c, d, e].

�� F = aF = a

�� S = bS = b

�� Tail = [c, d, e]Tail = [c, d, e]

Page 76: AI 08226 Prolog (PROgramming in LOGic)

76

Accessing Elements of A List*

�� Lists are sequential structuresLists are sequential structures

��Access is via recursionAccess is via recursion

��Remove head, then head from tail, ... , until empty listRemove head, then head from tail, ... , until empty list

�� writelistwritelist([]).([]).

�� writelist([H|Tailwritelist([H|Tail]):]):-- write(H), write(H), nlnl, , writelist(Tailwritelist(Tail).).

�� ??-- trace, writelist([5, 4, 3]).trace, writelist([5, 4, 3]).

�� writelist([5, 4, 3]) ? write(5) ? writelist([5, 4, 3]) ? write(5) ? nlnl ? writelist([4, 3]) ? ? writelist([4, 3]) ?

�� writelist([4, 3])?writelist([4, 3])? write(4) ?write(4) ? nlnl ? ? writelist([3]) ? writelist([3]) ?

�� writelist([3])?writelist([3])? write(3) ? write(3) ? nlnl ? ? writelistwritelist([]) ? ([]) ?

�� writelistwritelist([]) ?([]) ?

Page 77: AI 08226 Prolog (PROgramming in LOGic)

77

Building a List from Input*�� buildlist([H|Tailbuildlist([H|Tail]):]):-- read(H), not (H = end),read(H), not (H = end),

�� buildlist(Tailbuildlist(Tail).).

�� buildlistbuildlist([]).([]).

�� ??-- buildlist(Alistbuildlist(Alist).).

�� : : zebadeezebadee..

�� : : dylandylan..

�� : : florenceflorence..

�� : : brianbrian..

�� : end.: end.

�� AlistAlist = [= [zebadeezebadee, , dylandylan, , florenceflorence, , brianbrian] ]

�� YesYes

Page 78: AI 08226 Prolog (PROgramming in LOGic)

78

Tracing Buildlist�� ??-- trace, trace, buildlist(Alistbuildlist(Alist).).

�� buildlist(_G237) ? read(a) ? not a=end ? buildlist(_G237) ? read(a) ? not a=end ?

�� buildlist(_G328) ? read(b) ? not b=end ? buildlist(_G328) ? read(b) ? not b=end ?

�� buildlist(_G334) ? read(end) ? not end=end ? buildlist(_G334) ? read(end) ? not end=end ?

�� end=end ? end=end ?

�� Fail: ( 11) not end=end ? Fail: ( 11) not end=end ?

�� Redo: buildlist(_G334) ? Redo: buildlist(_G334) ? buildlistbuildlist([]) ? ([]) ?

�� AlistAlist = [a, b] = [a, b]

�� YesYes

�� buildlistbuildlist works becauseworks because

��AlistAlist = [a, b, | []] unifies with = [a, b, | []] unifies with AlistAlist = [a, b]= [a, b]

Page 79: AI 08226 Prolog (PROgramming in LOGic)

79

Testing for a list - is_list/1 (built-in)

�� is_list([]).is_list([]).

�� is_list([ _ | Tail ]):is_list([ _ | Tail ]):-- is_list(Tail).is_list(Tail).

��??-- is_list(a).is_list(a). NoNo

��??-- is_list("a").is_list("a"). YesYes

��??-- is_list([a, b, c, d]).is_list([a, b, c, d]). YesYes

��??-- is_list([a | b, c, d]).is_list([a | b, c, d]). NO!NO!

��??-- is_list([a | [b, c, d]]).is_list([a | [b, c, d]]). YesYes

��??-- is_list([ is_list([ fredfred | | fredafreda ]).]). YesYes

��??-- is_list([atom|List]).is_list([atom|List]). NO!NO!

Page 80: AI 08226 Prolog (PROgramming in LOGic)

80

Useful List Predicates*

�� Reversing a list Reversing a list -- reverse/2 (builtreverse/2 (built--in)in)

��List elements transferred from front of first list to headList elements transferred from front of first list to head

�� of second listof second list

��When first list is empty, the second list is the final listWhen first list is empty, the second list is the final list

��reverse(L1, L2):reverse(L1, L2):-- rev(L1, [], L2).rev(L1, [], L2).

��rev([], L, L).rev([], L, L).

��rev([H | T], L2, L3):rev([H | T], L2, L3):-- rev(T, [H | L2], L3).rev(T, [H | L2], L3).

�� ??-- reverse([1, 2, 3, 4], L).reverse([1, 2, 3, 4], L).

�� L = [4, 3, 2, 1]L = [4, 3, 2, 1]

Page 81: AI 08226 Prolog (PROgramming in LOGic)

81

Useful List Predicates*

�� Testing for list membership Testing for list membership -- member/2 (builtmember/2 (built--in)in)

��Predicate succeeds when element matches to head of Predicate succeeds when element matches to head of

listlist

��Otherwise recursively calls itself with the tail of the Otherwise recursively calls itself with the tail of the

list until the list is emptylist until the list is empty

��member(X, [X | _member(X, [X | _varvar ]).]).

��member(X, [ _member(X, [ _varvar | T]):| T]):-- member(X, T).member(X, T).

�� ??-- member(heron, [bat, heron, owl]).member(heron, [bat, heron, owl]).

�� YesYes

Page 82: AI 08226 Prolog (PROgramming in LOGic)

82

Useful List Predicates*

�� Appending to lists Appending to lists -- append/3 (builtappend/3 (built--in)in)

��Predicate appends list L2 onto end of list L1 to give L3Predicate appends list L2 onto end of list L1 to give L3

��append( [ ] , L, L).append( [ ] , L, L).

��append( [H | L1], L2, [ H | L3]):append( [H | L1], L2, [ H | L3]):--

�� append(L1, L2, L3).append(L1, L2, L3).

�� ??-- append([1, 2], [3, 4], L).append([1, 2], [3, 4], L).

�� L = [1, 2, 3, 4]L = [1, 2, 3, 4]

Page 83: AI 08226 Prolog (PROgramming in LOGic)

83

Useful List Predicates

�� Appending to lists Appending to lists -- reverse/2 (builtreverse/2 (built--in)in)

��Predicate reverses list order from L1 to L2 or inversePredicate reverses list order from L1 to L2 or inverse

% reverse/2 makes use of reverse/3% reverse/2 makes use of reverse/3

reverse( [ ] , [ ]).reverse( [ ] , [ ]).

reverse( [H | L], Reverse):reverse( [H | L], Reverse):--

reverse(Lreverse(L, [H], Reverse)., [H], Reverse).

reverse( [ ], Reverse, Reverse).reverse( [ ], Reverse, Reverse).

reverse([Hreverse([H | L], L2, Reverse):| L], L2, Reverse):--

reverse(Lreverse(L, [H | L2], Reverse)., [H | L2], Reverse).

Page 84: AI 08226 Prolog (PROgramming in LOGic)

84

Useful List Predicates*

�� Delete item from lists Delete item from lists -- delete/3 (builtdelete/3 (built--in)in)��Takes list and deletes all instances of item to build second lisTakes list and deletes all instances of item to build second listt

��delete( [ ] , _delete( [ ] , _varvar , [ ])., [ ]).

��delete( [ X | L1] , X, L2):delete( [ X | L1] , X, L2):-- delete(L1, X, L2).delete(L1, X, L2).

��delete( [ H | L1] , X, [ H | L2]):delete( [ H | L1] , X, [ H | L2]):-- delete(L1, X, L2).delete(L1, X, L2).

�� ??-- delete([a, b, c], a, L).delete([a, b, c], a, L).

�� L = [b, c] L = [b, c]

�� ??-- delete([a, b, c], [a], L).delete([a, b, c], [a], L).

�� L = [a, b, c] L = [a, b, c]

�� ??-- delete([a, b, c, a], a, L).delete([a, b, c, a], a, L).

�� L = [b, c] L = [b, c]

Page 85: AI 08226 Prolog (PROgramming in LOGic)

85

Deleting the elements of a list

�� A different delete predicateA different delete predicate

��delete1(Item, [Item|Tail], Tail).delete1(Item, [Item|Tail], Tail).

��delete1(Item, [H | Tail], [H | List]):delete1(Item, [H | Tail], [H | List]):--

�� delete1(Item, Tail, List).delete1(Item, Tail, List).

��??-- delete1(a, [a, b, c], L).delete1(a, [a, b, c], L).

�� L = [b, c] L = [b, c]

��??-- delete1(I, [a, b, c], L).delete1(I, [a, b, c], L).

�� I = aI = a L = [b, c] ;L = [b, c] ;

�� I = bI = b L = [a, c] ;L = [a, c] ;

�� I = cI = c L = [a, b] ; L = [a, b] ;

�� NoNo

Page 86: AI 08226 Prolog (PROgramming in LOGic)

86

Permuting the elements of a list

permutation([ ], [ ]).permutation([ ], [ ]).

permutation(List, [ H | Tail ]):permutation(List, [ H | Tail ]):--

delete1(H, List, Rest),delete1(H, List, Rest),

permutation( Rest, Tail ).permutation( Rest, Tail ).

��??-- permutation([a, b, c], L).permutation([a, b, c], L).

�� L = [a, b, c] ;L = [a, b, c] ;

�� L = [a, c, b] ;L = [a, c, b] ;

�� L = [b, a, c] ;L = [b, a, c] ;

�� L = [b, c, a] ;L = [b, c, a] ;

�� L = [c, a, b] ;L = [c, a, b] ;

�� L = [c, b, a] ;L = [c, b, a] ;

Page 87: AI 08226 Prolog (PROgramming in LOGic)

87��??-- trace, permutation([a, b, c], L).trace, permutation([a, b, c], L).

��delete1(a, [a, b, c], [b, c]) ? permutation([b, c], [b, c]) ?delete1(a, [a, b, c], [b, c]) ? permutation([b, c], [b, c]) ?

��L = [a, b, c] ;L = [a, b, c] ;

��delete1(c, [b, c], [b]) ? creep permutation([b], [b]) ?delete1(c, [b, c], [b]) ? creep permutation([b], [b]) ?

��permutation([b, c], [c, b]) ?permutation([b, c], [c, b]) ?

��permutation([a, b, c], [a, c, b]) ?permutation([a, b, c], [a, c, b]) ?

��L = [a, c, b] ;L = [a, c, b] ;

��delete1(b, [a, b, c], [a, c]) ? permutation([a, c], [a, c]) ? delete1(b, [a, b, c], [a, c]) ? permutation([a, c], [a, c]) ?

��L = [b, a, c] ;L = [b, a, c] ;

��delete1(c, [a, c], [a]) ? permutation([a], [a]) ?delete1(c, [a, c], [a]) ? permutation([a], [a]) ?

��permutation([a, c], [c, a]) ? permutation([a, c], [c, a]) ?

��permutation([a, b, c], [b, c, a]) ? permutation([a, b, c], [b, c, a]) ?

��L = [b, c, a] L = [b, c, a]

Page 88: AI 08226 Prolog (PROgramming in LOGic)

88

Built-In List Predicates*�� =../2=../2 ``Univ.'' Term to list conversion``Univ.'' Term to list conversion

�� atom_chars/2atom_chars/2 Convert between atom and list of ASCII valuesConvert between atom and list of ASCII values

�� name/2name/2 Convert between atom and list of ASCII charactersConvert between atom and list of ASCII characters

�� concat_atom/2concat_atom/2 Append a list of atomsAppend a list of atoms

�� concat_atom/3concat_atom/3 Append a list of atoms with separatorAppend a list of atoms with separator

�� string_to_list/2string_to_list/2 Conversion between string and list of ASCIIConversion between string and list of ASCII

�� is_list/1is_list/1 Type check for a listType check for a list

�� proper_list/1proper_list/1 Type check for listType check for list

�� append/3append/3 Concatenate listsConcatenate lists

�� member/2member/2 Element is member of a listElement is member of a list

�� delete/3delete/3 Delete all matching members from a listDelete all matching members from a list

�� select/3select/3 Select element of a listSelect element of a list

Page 89: AI 08226 Prolog (PROgramming in LOGic)

89

More Built-in List Predicates*�� nth0/3nth0/3 NN--thth element of a list (0element of a list (0--based)based)

�� nth1/3nth1/3 NN--thth element of a list (1element of a list (1--based)based)

�� last/2 last/2 Last element of a listLast element of a list

�� reverse/2reverse/2 Inverse the order of the elements in a listInverse the order of the elements in a list

�� flatten/2flatten/2 Transform nested list into flat listTransform nested list into flat list

�� length/2length/2 Length of a listLength of a list

�� merge/3merge/3 Merge two sorted listsMerge two sorted lists

�� list_to_set/2list_to_set/2 Remove duplicatesRemove duplicates

�� sort/2sort/2 Sort elements in a listSort elements in a list

�� checklist/2checklist/2 Invoke goal on all members of a listInvoke goal on all members of a list

�� maplist/3maplist/3 Transform all elements of a listTransform all elements of a list

�� sublist/3sublist/3 Determine elements that meet conditionDetermine elements that meet condition

Page 90: AI 08226 Prolog (PROgramming in LOGic)

90

Asserting Predicates

�� assert/1 assert/1 -- assert(?Term)assert(?Term)

��adds term to predicate databaseadds term to predicate database

��??-- listing(fish).listing(fish).

�� fish(tuna, big).fish(tuna, big).

�� fish(shark, big).fish(shark, big).

��??-- assert( fish(guppy, small) ).assert( fish(guppy, small) ).

��??-- listing(fish).listing(fish).

�� fish(tuna, big).fish(tuna, big).

�� fish(shark, big).fish(shark, big).

�� fish(guppy, small).fish(guppy, small).

��Adds asserted term to end of database of predicatesAdds asserted term to end of database of predicates

Page 91: AI 08226 Prolog (PROgramming in LOGic)

91

Asserting Predicates

�� assert/1 assert/1 -- will duplicate term in predicate databasewill duplicate term in predicate database

��??-- listing(fish).listing(fish).

�� fish(tuna, big).fish(tuna, big).

�� fish(shark, big).fish(shark, big).

��??-- assert( fish(tuna, big) ).assert( fish(tuna, big) ).

��??-- listing(fish).listing(fish).

�� fish(tuna, big).fish(tuna, big).

�� fish(shark, big).fish(shark, big).

�� fish(tuna, big).fish(tuna, big).

��Adds asserted term to end of database of predicatesAdds asserted term to end of database of predicates

Page 92: AI 08226 Prolog (PROgramming in LOGic)

92

Asserting Predicates

�� assert/1 assert/1 -- can assert rules toocan assert rules too

��??-- listing(big).listing(big).

�� [WARNING: No predicates for `big'][WARNING: No predicates for `big']

�� NoNo

��??-- assert( big(X):assert( big(X):-- fish(X, big) ).fish(X, big) ).

�� X = _G279 X = _G279

��??-- listing(big).listing(big).

�� big(A) :big(A) :-- fish(A, big).fish(A, big).

��??-- big(F).big(F).

�� F = tuna ;F = tuna ;

�� F = sharkF = shark

Page 93: AI 08226 Prolog (PROgramming in LOGic)

93

Static and Dynamic Clauses

�� Cannot assert and retract Cannot assert and retract functor/arityfunctor/arity

�� IF static clauseIF static clause

fact( apple, fruit, edible).fact( apple, fruit, edible).

fact( jackfruit, fruit, disgusting ).fact( jackfruit, fruit, disgusting ).

�� fact/3 cannot be asserted or retractedfact/3 cannot be asserted or retracted

�� Have to make dynamic using HEADHave to make dynamic using HEAD--Less RuleLess Rule

::-- dynamic( fact/3).dynamic( fact/3).

�� Then the above codeThen the above code

�� Can now retract or assert fact/3Can now retract or assert fact/3

Page 94: AI 08226 Prolog (PROgramming in LOGic)

94

Asserting Predicates - Variations��??-- apropos(assert).apropos(assert).

�� assert/1assert/1 Add a clause to the databaseAdd a clause to the database

�� asserta/1asserta/1 Add a clause to the database (first)Add a clause to the database (first)

�� assertz/1assertz/1 Add a clause to the database (last)Add a clause to the database (last)

�� ??-- listing(fish).listing(fish).

�� fish(guppy, small).fish(guppy, small).

�� fish(tuna, big).fish(tuna, big).

�� ??-- asserta(fish(sharkasserta(fish(shark, big))., big)).

�� ??-- listing(fish).listing(fish).

�� fish(shark, big).fish(shark, big).

�� fish(guppy, small).fish(guppy, small).

�� fish(tuna, big).fish(tuna, big).

Page 95: AI 08226 Prolog (PROgramming in LOGic)

95

Retracting Predicates

�� retract/1 retract/1 -- retract(?Term)retract(?Term)

��deletes term to predicate databasedeletes term to predicate database

��??-- listing(fish).listing(fish).

�� fish(tuna, big).fish(tuna, big).

�� fish(shark, big).fish(shark, big).

��??-- retract( fish(shark, big) ).retract( fish(shark, big) ).

��??-- listing(fish).listing(fish).

�� fish(tuna, big).fish(tuna, big).

��??-- retract( fish(tuna, _) ).retract( fish(tuna, _) ).

��??-- listing(fish).listing(fish).

�� YesYes

Page 96: AI 08226 Prolog (PROgramming in LOGic)

96

Retracting Predicates

�� Can give different levels of specificityCan give different levels of specificity

��??-- listing(fish).listing(fish).

�� fish(tuna, big).fish(tuna, big).

�� fish(shark, big).fish(shark, big).

�� fish(marlin, big).fish(marlin, big).

��??-- retract( fish(shark, _) ).retract( fish(shark, _) ).

�� retracts first instance matching to fish(shark, _)retracts first instance matching to fish(shark, _)

��??-- retract( fish( _, _) ).retract( fish( _, _) ).

�� retracts first instance matching to fish( _, _)retracts first instance matching to fish( _, _)

��??-- listing(fish).listing(fish).

�� fish(marlin, big).fish(marlin, big).

Page 97: AI 08226 Prolog (PROgramming in LOGic)

97

Retracting Predicates

�� Can use retract to delete rules tooCan use retract to delete rules too

�� retract( ( big(X):retract( ( big(X):-- fish(X, big) ) ).fish(X, big) ) ).

�� X = _G291 X = _G291

��??-- listing(big).listing(big).

�� YesYes

�� Retractall/1 Retractall/1 -- remove all instances matching termremove all instances matching term

��??-- retractall(fishretractall(fish(_,_)).(_,_)).

��??-- listing(fish).listing(fish).

�� YesYes

Page 98: AI 08226 Prolog (PROgramming in LOGic)

98

Does a clause exist?

�� clause/2clause/2

�� clause(?Head, ?Body)clause(?Head, ?Body)

��Succeeds when Head can be unified with a clause head Succeeds when Head can be unified with a clause head

and Body with the corresponding clause body. and Body with the corresponding clause body.

��Gives alternative clauses on backtracking.Gives alternative clauses on backtracking.

��For facts Body is unified with the atom true. For facts Body is unified with the atom true.

��Normally clause/2 is used to find clause definitions for Normally clause/2 is used to find clause definitions for

a predicate, but it can also be used to find clause heads a predicate, but it can also be used to find clause heads

for some body template.for some body template.

Page 99: AI 08226 Prolog (PROgramming in LOGic)

99

Does a clause exist?��??-- listing.listing.

�� big(X):big(X):-- fish(X, big) .fish(X, big) .

�� fish(tuna, big).fish(tuna, big).

�� fish(marlin, big).fish(marlin, big).

��??-- clause(fish(F, S), Body).clause(fish(F, S), Body).

�� F = tunaF = tuna

�� S = bigS = big

�� Body = true ;Body = true ;

�� F = marlinF = marlin

�� S = bigS = big

�� Body = true ;Body = true ;

Page 100: AI 08226 Prolog (PROgramming in LOGic)

100

Does a clause exist?��??-- listing.listing.

�� big(X):big(X):-- fish(X, big) .fish(X, big) .

�� fish(tuna, big).fish(tuna, big).

�� fish(marlin, big).fish(marlin, big).

��What Rules Exist with given BodyWhat Rules Exist with given Body

��??-- clause(Head, fish(F,S)).clause(Head, fish(F,S)).

�� Head = big(_G237)Head = big(_G237)

�� F = _G237F = _G237

�� S = big ;S = big ;

�� NoNo

Page 101: AI 08226 Prolog (PROgramming in LOGic)

101

Combining clause and retract��??-- listing.listing.

�� big(X):big(X):-- fish(X, big) .fish(X, big) .

�� fish(tuna, big).fish(tuna, big).

�� fish(marlin, big).fish(marlin, big).

�� If rule with fish/2 as body exists retract itIf rule with fish/2 as body exists retract it

��??-- clause(Head, fish(F,S)), retract(Head:clause(Head, fish(F,S)), retract(Head:-- fish(F, S)).fish(F, S)).

�� Head = big(_G237)Head = big(_G237)

�� F = _G237F = _G237

�� S = big ;S = big ;

�� NoNo

Page 102: AI 08226 Prolog (PROgramming in LOGic)

102

Finding all occurrences of a predicate

�� findall/3 findall/3 -- built in predicatebuilt in predicate

�� findall(+Varfindall(+Var, +Goal, , +Goal, --Bag)Bag)

��Creates a list of the instantiations Creates a list of the instantiations VarVar gets gets

successively on backtracking over Goal and unifies the successively on backtracking over Goal and unifies the

result with Bag. Succeeds with an empty list if Goal result with Bag. Succeeds with an empty list if Goal

has no solutions. has no solutions.

��Also see:Also see: help( help( setofsetof ), help( ), help( bagofbagof ))

�� fish(shark, big). fish(guppy, small). fish(tuna, big).fish(shark, big). fish(guppy, small). fish(tuna, big).

��??-- findall(Fishfindall(Fish, fish(Fish, _), Fishes)., fish(Fish, _), Fishes).

�� Fish = _G315Fish = _G315

�� Fishes = [shark, guppy, tuna]Fishes = [shark, guppy, tuna]

Page 103: AI 08226 Prolog (PROgramming in LOGic)

103

More on Findall��??-- assert( fish(shark, big) ).assert( fish(shark, big) ).

��??-- assert( fish(tuna, big) ).assert( fish(tuna, big) ).

��??-- assert( fish(guppy, small) ).assert( fish(guppy, small) ).

��??-- findall(Fishfindall(Fish, fish(Fish, big), Fishes)., fish(Fish, big), Fishes).

�� Fish = _G327Fish = _G327

�� Fishes = [shark, tuna]Fishes = [shark, tuna]

��Now add further factNow add further fact

��??-- assert( fish(shark, big) ).assert( fish(shark, big) ).

��??-- findall(Fishfindall(Fish, fish(Fish, big), Fishes)., fish(Fish, big), Fishes).

�� Fish = _G327Fish = _G327

�� Fishes = [shark, tuna, shark]Fishes = [shark, tuna, shark]

Page 104: AI 08226 Prolog (PROgramming in LOGic)

104

Compound Terms - Findall

�� CompundCompund terms can be used to associate itemsterms can be used to associate items

��??-- (A:B) = (atom1:atom2).(A:B) = (atom1:atom2).

�� A = atom1A = atom1

�� B = atom2 B = atom2

�� Can be used to pull items together in listsCan be used to pull items together in lists

�� Multiple joining characters permittedMultiple joining characters permitted

��atom1:atom2, atom1atom1:atom2, atom1--atom2, at1+at2, at1/at2 etcatom2, at1+at2, at1/at2 etc

�� Compare: question of programming preferenceCompare: question of programming preference

�� [ [[ [bertbert, , frenchfrench, singer], [, singer], [jakejake, , dutchdutch, , djdj] ]] ]

�� [ [ bertbert--frenchfrench--singersinger, , jakejake--dutchdutch--djdj]]

Page 105: AI 08226 Prolog (PROgramming in LOGic)

105

Compound Terms via Findall�� fish(shark, big)fish(shark, big)

�� fish(tuna, big) fish(tuna, big)

�� fish(guppy, small)fish(guppy, small)

��??-- findall(Fishfindall(Fish--Size, fish(Fish, Size), Size, fish(Fish, Size), AListAList).).

�� Fish = _G327Fish = _G327

�� Size = _G329Size = _G329

�� AListAList = [shark= [shark--big, tunabig, tuna--big, guppybig, guppy--small]small]

��??-- findall([Afindall([A, B], fish(A, B), As)., B], fish(A, B), As).

�� A = _G157A = _G157

�� B = _G160B = _G160

�� As = [[shark, big], [guppy, small], [tuna, big]] As = [[shark, big], [guppy, small], [tuna, big]]

Page 106: AI 08226 Prolog (PROgramming in LOGic)

106

Using a FSM to Control a simple agent

�� logical structurelogical structure

Senses

Input FSM

Actions

Output

State

Page 107: AI 08226 Prolog (PROgramming in LOGic)

107

% FSM Controller Agent% FSM Controller Agent

% agent/5 % agent/5 -- agent(Name, X, Y, State, Direction).agent(Name, X, Y, State, Direction).

% object/3 % object/3 -- object(Name, X, Y).object(Name, X, Y).

% define thing over agent/5 and object/3% define thing over agent/5 and object/3

thing(X):thing(X):-- agent(X, _v2, _v3, _v4, _v5).agent(X, _v2, _v3, _v4, _v5).

thing(X):thing(X):-- object(X, _v2, _v3).object(X, _v2, _v3).

% define sense/2 over all things other than agent% define sense/2 over all things other than agent

senses(Agent, Things):senses(Agent, Things):--

agent(Agent, _v2, _v3, _v4, _v5),agent(Agent, _v2, _v3, _v4, _v5),

findall(Xfindall(X, (thing(X), not(X==Agent)), Things)., (thing(X), not(X==Agent)), Things).

Prolog for Senses for FSM-Agent

Page 108: AI 08226 Prolog (PROgramming in LOGic)

108input(_Agent, [], input(_Agent, [], spacefreespacefree):):-- !.!.

input(Agent, [Thing | _rest], input(Agent, [Thing | _rest], spaceblockspaceblock):):--

spaceblock(Agentspaceblock(Agent, Thing), !., Thing), !.

input(Agent, [_head|Rest], Input):input(Agent, [_head|Rest], Input):--

input(Agent, Rest, Input).input(Agent, Rest, Input).

spaceblock(Agentspaceblock(Agent, Thing):, Thing):--

agent(Agent,Xagentagent(Agent,Xagent, , Yagent,_stateYagent,_state, Direction),, Direction),

object(Thing, object(Thing, XobjectXobject, , YobjectYobject),),

block(Xagentblock(Xagent, , YagentYagent, Direction, , Direction, XobjectXobject, , YobjectYobject).).

spaceblock(Agentspaceblock(Agent, Thing):, Thing):--

agent(Agent,Xagentagent(Agent,Xagent, , Yagent,_stateYagent,_state, Direction),, Direction),

agent(Thing, agent(Thing, XobjectXobject, , YobjectYobject, _state2, _direction),, _state2, _direction),

block(Xagentblock(Xagent, , YagentYagent, Direction, , Direction, XobjectXobject, , YobjectYobject).).

Page 109: AI 08226 Prolog (PROgramming in LOGic)

109

% block/5% block/5

% % block(Xagentblock(Xagent, , YagentYagent, Direction, , Direction, XobjectXobject, , YobjectYobject). ).

% Only need to define % Only need to define spaceblockspaceblock casescases

% Top left is origin in this world% Top left is origin in this world

block(X, Y1, up, X, Y2):block(X, Y1, up, X, Y2):-- Y2 is Y1Y2 is Y1--1, !.1, !.

block(X, Y1, down, X, Y2):block(X, Y1, down, X, Y2):-- Y2 is Y1+1, !.Y2 is Y1+1, !.

block(X1, Y, left, X2, Y):block(X1, Y, left, X2, Y):-- X2 is X1X2 is X1--1, !.1, !.

block(X1, Y, right, X2, Y):block(X1, Y, right, X2, Y):-- X2 is X1X2 is X1--1, !.1, !.

When is a thing a block?

Page 110: AI 08226 Prolog (PROgramming in LOGic)

110

% actions/5% actions/5

% actions(Direction, Output, X,Y, NX, % actions(Direction, Output, X,Y, NX, NY,NewDirectionNY,NewDirection),),

actions(up, ahead, X, Y, X, NY, up):actions(up, ahead, X, Y, X, NY, up):-- NY is YNY is Y--1.1.

actions(right, ahead, X, Y, NX, Y, right):actions(right, ahead, X, Y, NX, Y, right):-- NX is X+1. NX is X+1.

actions(down, ahead, X, Y, X, NY, down):actions(down, ahead, X, Y, X, NY, down):-- NY is Y+1. NY is Y+1.

actions(left, ahead, X, Y, NX, Y, left):actions(left, ahead, X, Y, NX, Y, left):-- NX is XNX is X--1. 1.

actions(up, actions(up, turnleftturnleft, X, Y, X, Y, left):, X, Y, X, Y, left):-- !.!.

actions(right, actions(right, turnleftturnleft, X, Y, X, Y, up):, X, Y, X, Y, up):-- !. !.

actions(down, actions(down, turnleftturnleft, X, Y, X, Y, right):, X, Y, X, Y, right):-- !. !.

actions(left, actions(left, turnleftturnleft, X, Y, X, Y, down):, X, Y, X, Y, down):-- !. !.

actions(Direction, nothing, X, Y, X, Y, Direction):actions(Direction, nothing, X, Y, X, Y, Direction):-- !.!.

Mapping Output to Actions

Page 111: AI 08226 Prolog (PROgramming in LOGic)

111

% run_agent/1% run_agent/1

run_agent(Agent):run_agent(Agent):--

agent(Agent, X, Y, State, Direction),agent(Agent, X, Y, State, Direction),

senses(Agent, Things),senses(Agent, Things),

input(Agent, Things, Input),input(Agent, Things, Input),

fsm(Inputfsm(Input, State, , State, NewStateNewState, Output),, Output),

actions(Direction, Output, X,Y, NX, actions(Direction, Output, X,Y, NX, NY,NewDirectionNY,NewDirection),),

retract( agent(Agent, X, Y, State, Direction) ),retract( agent(Agent, X, Y, State, Direction) ),

assert( agent(Agent, assert( agent(Agent, NewXNewX, , NewYNewY,,

NewStateNewState, , NewDirectionNewDirection)).)).

How is an agent run?

Page 112: AI 08226 Prolog (PROgramming in LOGic)

112

Full FSM-Agent Execution

FSM1.PL compiled 0.00 sec, 8,128 bytesFSM1.PL compiled 0.00 sec, 8,128 bytes

??-- assert(agent(a1, 10,19, assert(agent(a1, 10,19, aksfaksf, up))., up)).

??-- assert(agent(a2,10,20,aksf,up)).assert(agent(a2,10,20,aksf,up)).

??-- run_agent(a2), listing(agent).run_agent(a2), listing(agent).

agent(a2, 10, 20, agent(a2, 10, 20, aksbaksb, up)., up).

??-- run_agent(a2), listing(agent).run_agent(a2), listing(agent).

agent(a2, 10, 20, agent(a2, 10, 20, aksbaksb, up)., up).

??-- run_agent(a2), listing(agent).run_agent(a2), listing(agent).

agent(a2, 9, 20, agent(a2, 9, 20, aksfaksf, left)., left).

Page 113: AI 08226 Prolog (PROgramming in LOGic)

113

Compound Terms

�� Can use simple terms as arguments to predicatesCan use simple terms as arguments to predicates

��??-- assert(predicate(arg1, arg2, 8)).assert(predicate(arg1, arg2, 8)).

��??-- predicate(A,B,C), atom(A), atom(B), integer(C).predicate(A,B,C), atom(A), atom(B), integer(C).

�� YesYes

��??-- predicate(A,B,C), atom(A), atom(B), atom(C).predicate(A,B,C), atom(A), atom(B), atom(C).

�� NoNo

�� Can use simple terms as list elementsCan use simple terms as list elements

��??-- assert(predicate([a, b, c, d])).assert(predicate([a, b, c, d])).

��??-- predicate([H|R]), atom(H).predicate([H|R]), atom(H).

�� YesYes

Page 114: AI 08226 Prolog (PROgramming in LOGic)

114

Compound Terms As Associations�� However in some situations want to associateHowever in some situations want to associate

�� For example, sense For example, sense -- associate distance and objectassociate distance and object

��assert(sense(agent1, [agent2, object1], [25, 50])).assert(sense(agent1, [agent2, object1], [25, 50])).

�� is one way but need to manipulate both listsis one way but need to manipulate both lists

��output(_agoutput(_ag, [ ], [ ]). , [ ], [ ]).

��output(Agent, [H1|R1], [H2|R2]):output(Agent, [H1|R1], [H2|R2]):--

�� write(write(‘‘Distance from Distance from ‘‘), write(Agent), write(), write(Agent), write(‘‘ to to ‘‘),),

�� write(H1), write(write(H1), write(‘‘ is is ‘‘), write(H2), ), write(H2), nlnl,,

�� output(Agent, R1, R2).output(Agent, R1, R2).

�� ??-- sense(A,B,C), output(A,B,C).sense(A,B,C), output(A,B,C).

��Distance from agent1 to agent2 is 25Distance from agent1 to agent2 is 25

��Distance from agent1 to object1 is 50Distance from agent1 to object1 is 50

Page 115: AI 08226 Prolog (PROgramming in LOGic)

115

Alternative is to use compound terms

�� Advantage is sort only one listAdvantage is sort only one list

��assert(sense(agent1, [(agent2, 15), (object1,5)])).assert(sense(agent1, [(agent2, 15), (object1,5)])).

��But need to manipulate compound termBut need to manipulate compound term

��output(_agoutput(_ag, [ ]). , [ ]).

��output(Agent, [(H1,H2)|R]):output(Agent, [(H1,H2)|R]):--

�� write(write(‘‘Distance from Distance from ‘‘), write(Agent), write(), write(Agent), write(‘‘ to to ‘‘),),

�� write(H1), write(write(H1), write(‘‘ is is ‘‘), write(H2), ), write(H2), nlnl,,

�� output(Agent, R).output(Agent, R).

�� ??-- sense(A,B), output(A,B).sense(A,B), output(A,B).

��Distance from agent1 to agent2 is 15Distance from agent1 to agent2 is 15

��Distance from agent1 to object1 is 5Distance from agent1 to object1 is 5

��See file: See file: compound.plcompound.pl

Page 116: AI 08226 Prolog (PROgramming in LOGic)

116

Alternative: Lists as compound terms

�� Syntax of Compound terms up to userSyntax of Compound terms up to user

��assert(sense(agent1, [[agent2, 15], [object1,5]])).assert(sense(agent1, [[agent2, 15], [object1,5]])).

��Need to manipulate nested list compound termNeed to manipulate nested list compound term

��output(_agoutput(_ag, [ ]). , [ ]).

��output(Agent, [[H1,H2]|R]):output(Agent, [[H1,H2]|R]):--

�� write(write(‘‘Distance from Distance from ‘‘), write(Agent), write(), write(Agent), write(‘‘ to to ‘‘),),

�� write(H1), write(write(H1), write(‘‘ is is ‘‘), write(H2), ), write(H2), nlnl,,

�� output(Agent, R).output(Agent, R).

�� ??-- sense(A,B), output(A,B).sense(A,B), output(A,B).

��Distance from agent1 to agent2 is 15Distance from agent1 to agent2 is 15

��Distance from agent1 to object1 is 5Distance from agent1 to object1 is 5

Page 117: AI 08226 Prolog (PROgramming in LOGic)

117

Alternative: Structure it yourself

�� Syntax of Compound terms up to userSyntax of Compound terms up to user

��assert(sense(agent1, [agent2assert(sense(agent1, [agent2--5, object15, object1--15])).15])).

��Need to manipulate this form of compound termNeed to manipulate this form of compound term

��output(_agoutput(_ag, [ ]). , [ ]).

��output(Agent, [H1output(Agent, [H1--H2|R]):H2|R]):--

�� write(write(‘‘Distance from Distance from ‘‘), write(Agent), write(), write(Agent), write(‘‘ to to ‘‘),),

�� write(H1), write(write(H1), write(‘‘ is is ‘‘), write(H2), ), write(H2), nlnl,,

�� output(Agent, R).output(Agent, R).

�� ??-- sense(A,B), output(A,B).sense(A,B), output(A,B).

��Distance from agent1 to agent2 is 5Distance from agent1 to agent2 is 5

��Distance from agent1 to object1 is 15Distance from agent1 to object1 is 15

�� Note some constructors NOT allowedNote some constructors NOT allowed

Page 118: AI 08226 Prolog (PROgramming in LOGic)

118

Programming Practice

�� Write a program to determine number of Write a program to determine number of

occurrences of given item in a listoccurrences of given item in a list

frequency(_, [ ], 0).frequency(_, [ ], 0).

frequency(Item, [ Item | Rest ], N):frequency(Item, [ Item | Rest ], N):--

frequency(Item, Rest, N1),frequency(Item, Rest, N1),

N is N1 +1.N is N1 +1.

frequency(Item, [ H | Rest ], N):frequency(Item, [ H | Rest ], N):--

not( Item = H ),not( Item = H ), % An optional line?% An optional line?

frequency(Item, Rest, N).frequency(Item, Rest, N).

��??-- frequency(A, [a, b, c, a], N).frequency(A, [a, b, c, a], N).

�� A = aA = a N = 2 N = 2

Page 119: AI 08226 Prolog (PROgramming in LOGic)

119

�� trace, frequency(b, [a, b, c, b], N).trace, frequency(b, [a, b, c, b], N).

��not b=a ?not b=a ? frequency(b, [b, c, b], _G329) ?frequency(b, [b, c, b], _G329) ?

�� frequency(b, [c, b], _L149) ?frequency(b, [c, b], _L149) ?

��not b=c ? frequency(b, [b], _L149) ?not b=c ? frequency(b, [b], _L149) ?

�� frequency(b, [], _L177) ?frequency(b, [], _L177) ? frequency(b, [], 0) ?frequency(b, [], 0) ?

��1 is 0+1 ?1 is 0+1 ? frequency(b, [b], 1) ?frequency(b, [b], 1) ?

�� frequency(b, [c, b], 1) ?frequency(b, [c, b], 1) ?

��2 is 1+1 ?2 is 1+1 ? frequency(b, [b, c, b], 2) ?frequency(b, [b, c, b], 2) ?

�� frequency(b, [a, b, c, b], 2) ?frequency(b, [a, b, c, b], 2) ?

�� N = 2;N = 2;

�� NoNo

Tracing Frequency

Page 120: AI 08226 Prolog (PROgramming in LOGic)

120Variation1 on Frequencyfrequency(_term, [ ], 0).frequency(_term, [ ], 0).

frequency(Item, [ Item | Rest ], N):frequency(Item, [ Item | Rest ], N):--

frequency(Item, Rest, N1),frequency(Item, Rest, N1),

N is N1 +1.N is N1 +1.

frequency(Item, [ _term | Rest ], N):frequency(Item, [ _term | Rest ], N):--

frequency(Item, Rest, N).frequency(Item, Rest, N).

��??-- frequency(a,[a, b, a, c], N).frequency(a,[a, b, a, c], N).

�� N = 2 ;N = 2 ;

�� N = 1 ;N = 1 ;

�� N = 1 ;N = 1 ;

�� N = 0 ;N = 0 ;

�� NoNo

Page 121: AI 08226 Prolog (PROgramming in LOGic)

121Variation 2 on Frequency with Cut (!)frequency(_term, [ ], 0).frequency(_term, [ ], 0).

frequency(Item, [ Item | Rest ], N):frequency(Item, [ Item | Rest ], N):--

!, frequency(Item, Rest, N1),!, frequency(Item, Rest, N1),

N is N1 +1.N is N1 +1.

frequency(Item, [ _term | Rest ], N):frequency(Item, [ _term | Rest ], N):--

frequency(Item, Rest, N).frequency(Item, Rest, N).

��??-- frequency(a,[a, b, a, c], N).frequency(a,[a, b, a, c], N).

�� N = 2 ;N = 2 ;

�� NoNo

��??-- frequency(A,[a, b, a, c], N).frequency(A,[a, b, a, c], N).

�� A = aA = a N = 2 ;N = 2 ;

�� NoNo

Page 122: AI 08226 Prolog (PROgramming in LOGic)

122

Controlling Backtracking - the Cut !�� The cut ! is an operator that halts backtrackingThe cut ! is an operator that halts backtracking

��The matching to the left cannot be undone for a goalThe matching to the left cannot be undone for a goal

??-- trace, frequency(a,[a, b, a, c], N).trace, frequency(a,[a, b, a, c], N).

N = 2 ;N = 2 ;

Redo: ( 12) frequency(a, [], _L162) ? creepRedo: ( 12) frequency(a, [], _L162) ? creep

Fail: ( 12) frequency(a, [], _L162) ? creepFail: ( 12) frequency(a, [], _L162) ? creep

Fail: ( 11) frequency(a, [c], _L162) ? creepFail: ( 11) frequency(a, [c], _L162) ? creep

Fail: ( 10) frequency(a, [a, c], _L135) ? creepFail: ( 10) frequency(a, [a, c], _L135) ? creep

Fail: ( 9) frequency(a, [b, a, c], _L135) ? creepFail: ( 9) frequency(a, [b, a, c], _L135) ? creep

Fail: ( 8) frequency(a, [a, b, a, c], _G323) ? creepFail: ( 8) frequency(a, [a, b, a, c], _G323) ? creep

NoNo

Page 123: AI 08226 Prolog (PROgramming in LOGic)

123

Goals and Cut�� Suppose rule Suppose rule pp with with subgoalssubgoals q, r, s, tq, r, s, t

��SubgoalSubgoal ss has has subgoalssubgoals a, b, c, da, b, c, d

p:p:-- q, r, s, t.q, r, s, t.

s:s:-- a, b, !, c, d.a, b, !, c, d.

��Suppose Suppose ss succeeds as far as succeeds as far as dd, which fails, which fails

��backtracking among backtracking among c, dc, d until they all failuntil they all fail

��unable to pass cut and because rule unable to pass cut and because rule ss has not failed as has not failed as

a whole yeta whole yet

��Prolog moves to Prolog moves to ss in the parent rule, then in the parent rule, then rr

�� if if rr succeeds a second time, execution moves forwardsucceeds a second time, execution moves forward

��and and ss is tried afresh (from the top of the database)is tried afresh (from the top of the database)

Page 124: AI 08226 Prolog (PROgramming in LOGic)

124

Repetition using the cut

�� Using Using repeat/0repeat/0 -- a standard Prolog predicatea standard Prolog predicate

�� Always succeed, provide an infinite number of choice Always succeed, provide an infinite number of choice

points.points.

input1:input1:-- read(X),read(X),

write(write(‘‘You typed: You typed: ‘‘), write(X), ), write(X), nlnl, X = end., X = end.

loop1:loop1:-- repeat, input1.repeat, input1.

input2:input2:-- read(X),read(X),

write('You typed: '), write(X), write('You typed: '), write(X), nlnl, !, X = end., !, X = end.

loop2:loop2:-- repeat, input2.repeat, input2.

�� loop2 (the cut) has the advantage of continuing with loop2 (the cut) has the advantage of continuing with

no stack problems no stack problems -- data is thrown away on lhs of cutdata is thrown away on lhs of cut

Page 125: AI 08226 Prolog (PROgramming in LOGic)

125

Running the two versions??-- input1.input1. ??-- input1. input1.

: hi.: hi. : end.: end.

You typed: hiYou typed: hi You typed: endYou typed: end

NoNo YesYes

??-- loop1.loop1. ??-- loop2.loop2.

: hi.: hi. :hi.:hi.

You typed: hiYou typed: hi You typed: hiYou typed: hi

: hi2.: hi2. :hi2.:hi2.

You typed: hi2You typed: hi2 You typed: hi2.You typed: hi2.

: end.: end. :end.:end.

You typed: endYou typed: end You typed: end.You typed: end.

YesYes YesYes

Page 126: AI 08226 Prolog (PROgramming in LOGic)

126

Mutually Exclusive Rules

�� If cuts are placed at the end of a clauseIf cuts are placed at the end of a clause

��Whether unit or nonWhether unit or non--unit, it succeeds at most just onceunit, it succeeds at most just once

�� Useful for one and only one match requiredUseful for one and only one match required

fish(marlin, big).fish(marlin, big).

fish(sailfish, big).fish(sailfish, big).

% same_rule/2 no cut% same_rule/2 no cut

same_rule(1, F):same_rule(1, F):-- fish(F, big).fish(F, big).

same_rule(2, F):same_rule(2, F):-- fish(F, big).fish(F, big).

% cut_rule % cut_rule -- same as above but with terminating cutsame as above but with terminating cut

cut_rule(1, F):cut_rule(1, F):-- fish(F, big), !.fish(F, big), !.

cut_rule(2, F):cut_rule(2, F):-- fish(F, big), !.fish(F, big), !.

Page 127: AI 08226 Prolog (PROgramming in LOGic)

127

So what happens?��??-- same_rule(X,Y).same_rule(X,Y).

��X = 1X = 1 Y = marlin ;Y = marlin ;

��X = 1X = 1 Y = sailfish ;Y = sailfish ;

��X = 2X = 2 Y = marlin ;Y = marlin ;

��X = 2X = 2 Y = sailfish ;Y = sailfish ;

��NoNo

��??-- cut_rule(X,Y).cut_rule(X,Y).

��X = 1X = 1 Y = marlin ;Y = marlin ;

��NoNo

Page 128: AI 08226 Prolog (PROgramming in LOGic)

128

Forcing new solutions & using cut

member1(X, [X|_]).member1(X, [X|_]).

member1(X, [ _term |T]):member1(X, [ _term |T]):-- member1(X, T).member1(X, T).

�� member1 will succeed for every occurrence of X member1 will succeed for every occurrence of X

in the listin the list

member2(X, [X| _term ]):member2(X, [X| _term ]):-- !.!.

member2(X, [ _term |T]):member2(X, [ _term |T]):-- member2(X, T).member2(X, T).

�� member2 will succeed just the once if X in list at member2 will succeed just the once if X in list at

least once or moreleast once or more

Page 129: AI 08226 Prolog (PROgramming in LOGic)

129

Run Time��member1 will succeed four times heremember1 will succeed four times here

??-- member1(a, [a, b, c, a, a, a, b]), write('hi'), member1(a, [a, b, c, a, a, a, b]), write('hi'), nlnl, fail., fail.

hihi

hihi

hihi

hihi

NoNo

��member2 will succeed just the oncemember2 will succeed just the once

??-- member2(a, [a, b, c, a, a, a, b]), write('hi'), member2(a, [a, b, c, a, a, a, b]), write('hi'), nlnl, fail., fail.

hihi

NoNo

Page 130: AI 08226 Prolog (PROgramming in LOGic)

130

The use of cut in negation�� Represent Represent ““Mary likes all animals but snakesMary likes all animals but snakes””

animal(snake).animal(snake).

animal(tiger).animal(tiger).

likes(marylikes(mary, snake):, snake):-- !, fail.!, fail.

likes(marylikes(mary, X):, X):-- animal(X).animal(X).

??-- likes(mary,tigerlikes(mary,tiger).).

YesYes

??-- likes(mary,snakelikes(mary,snake).).

NoNo

??-- likes(A,B).likes(A,B).

NoNo

Page 131: AI 08226 Prolog (PROgramming in LOGic)

131

The use of cut in negation - version2�� Represent Represent ““Mary likes all animals but snakesMary likes all animals but snakes””

animal(snake).animal(snake).

animal(tiger).animal(tiger).

likes(marylikes(mary, X):, X):-- animal(X), not(X=snake).animal(X), not(X=snake).

??-- likes(A,B).likes(A,B).

A = A = marymary

B = tiger ;B = tiger ;

NoNo

??-- likes(mary,snakelikes(mary,snake).).

NoNo

Page 132: AI 08226 Prolog (PROgramming in LOGic)

132

Negation as failure

�� Defining the relation different(X, Y)Defining the relation different(X, Y)

�� Different as in:Different as in:

��X and Y are not literally the sameX and Y are not literally the same

��X and Y do not matchX and Y do not match

�� the values of arithmetic expressions X and Y differthe values of arithmetic expressions X and Y differ

�� Take Second DefinitionTake Second Definition

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

different(X, Y).different(X, Y).

??-- different(a, b).different(a, b). ??-- different(a, a).different(a, a).

YesYes No No

Page 133: AI 08226 Prolog (PROgramming in LOGic)

133

Negation as failure��??-- animal(X), animal(Y), different(X, Y).animal(X), animal(Y), different(X, Y).

X = snakeX = snake Y = tiger ;Y = tiger ;

X = tigerX = tiger Y = snake ;Y = snake ;

NoNo

�� Alternative definition for different/2Alternative definition for different/2

different(X, Y):different(X, Y):-- not( X = Y ).not( X = Y ).

Page 134: AI 08226 Prolog (PROgramming in LOGic)

134

Principles of Good Programming

�� CorrectnessCorrectness

��Above all a program should be correctAbove all a program should be correct

�� EfficiencyEfficiency

��Good programs do not needlessly waste computer time Good programs do not needlessly waste computer time

and memory spaceand memory space

�� Transparency (readability)Transparency (readability)

��Avoid tricks that obscure the meaning of a programAvoid tricks that obscure the meaning of a program

Page 135: AI 08226 Prolog (PROgramming in LOGic)

135

Principles of Good Programming

�� ModifiabilityModifiability

��Good programs should be easy to modify and extendGood programs should be easy to modify and extend

�� RobustnessRobustness

��Programs should not crash immediately the user enters Programs should not crash immediately the user enters

incorrect or unexpected dataincorrect or unexpected data

�� DocumentationDocumentation

��A minimal documentation program comments and A minimal documentation program comments and

headerheader

Page 136: AI 08226 Prolog (PROgramming in LOGic)

136

Guidelines for achieving above

�� THINKTHINK about the problem to be solved. about the problem to be solved.

��When the problem is understood and solution well When the problem is understood and solution well

thought through, the actual coding is faster and easierthought through, the actual coding is faster and easier

�� Use Use STEPWISE REFINEMENTSTEPWISE REFINEMENT. .

��From topFrom top--level to bottomlevel to bottom--level solution.level solution.

��Each refinement step should intellectually manageableEach refinement step should intellectually manageable

�� i.e. small and clear enoughi.e. small and clear enough

�� Programming is CREATIVE, especially for Programming is CREATIVE, especially for

beginners new to specific programming conceptsbeginners new to specific programming concepts

��With experience becomes less of an art and more of a With experience becomes less of an art and more of a

craft. Ideas from similar problems we already know of.craft. Ideas from similar problems we already know of.

Page 137: AI 08226 Prolog (PROgramming in LOGic)

137

Thinking about prolog programs

�� Ontological DelineationOntological Delineation

��How do we find ideas for reducing problems to more How do we find ideas for reducing problems to more

easier easier subproblemssubproblems??

��How do we find proper How do we find proper subproblemssubproblems??

�� Problem P solved by solving {PProblem P solved by solving {P11, P, P22, , ……PPii,... ,... PPnn}}

�� Aspects to considerAspects to consider

��RecursionRecursion

��GeneralisationGeneralisation

��StructuralisationStructuralisation

��PicturesPictures

Page 138: AI 08226 Prolog (PROgramming in LOGic)

138

Use of Recursion

�� Principle is to split the given problem into casesPrinciple is to split the given problem into cases

�� Two groupsTwo groups

��1. Trivial or 1. Trivial or boundaryboundary casescases

��2. General cases whose solution is constructed from 2. General cases whose solution is constructed from

solutions of simpler versions of the problemsolutions of simpler versions of the problem

�� Recursion applies so naturally to prologRecursion applies so naturally to prolog

��Basic representation (lists) have recursive structureBasic representation (lists) have recursive structure

��A list is either empty A list is either empty

�� boundaryboundary casecase

��Or has a head and a tail that is itself a listOr has a head and a tail that is itself a list

�� general casegeneral case

Page 139: AI 08226 Prolog (PROgramming in LOGic)

139

Consider intersection of sets problem

�� intersection( Set1, Set2, Result).intersection( Set1, Set2, Result).

�� This can be split into two cases:This can be split into two cases:

��Boundary case: Boundary case: Set1 = [ ] or Set2 = []Set1 = [ ] or Set2 = []

�� If If Set1 = [ ]Set1 = [ ] then then Result = [Result = [ ]], regardless of , regardless of Set2Set2..

��General Case: General Case: Set1 = [ Head | Tail ]Set1 = [ Head | Tail ]

��To transform a list of this form do:To transform a list of this form do:

��Transform head of the listTransform head of the list

•• If If HeadHead membermember of of Set2Set2 then then ResultResult →→ [ Head | Result ][ Head | Result ]

��Then recursively call with Then recursively call with TailTail

•• Tail Tail →→ [ [ NewHeadNewHead | | NewTailNewTail ]]

��Eventually problem reduces to Eventually problem reduces to Boundary CaseBoundary Case [ ][ ]

Page 140: AI 08226 Prolog (PROgramming in LOGic)

140

Testing your code: Set UNION

�� Set union Set union -- sets can be represented as listssets can be represented as lists

��{ a, b, c, d } { a, b, c, d } ∪∪∪∪∪∪∪∪ { c, d, e }{ c, d, e } ⇒⇒⇒⇒⇒⇒⇒⇒ { a, b, c, d, e }{ a, b, c, d, e }

% Base case for recursion% Base case for recursion

setunionsetunion( [ ], X, X).( [ ], X, X).

% % RecurseRecurse without Head if member of L1without Head if member of L1

setunionsetunion( [H | T ], L1, L2):( [H | T ], L1, L2):--

member(H, L1), member(H, L1),

setunion(Tsetunion(T, L1, L2)., L1, L2).

% Otherwise % Otherwise RecurseRecurse with Head with Head

setunionsetunion( [ H | T ], L1, [ H | L2 ] ):( [ H | T ], L1, [ H | L2 ] ):--

setunionsetunion( T, L1, L2).( T, L1, L2).

Page 141: AI 08226 Prolog (PROgramming in LOGic)

141

Test cases: Set UNION without not

setunion([],[a],Lsetunion([],[a],L).).

L = [a] ;L = [a] ;

NoNo

??-- setunion([a],[],Lsetunion([a],[],L).).

L = [a] L = [a]

YesYes

??-- setunion([a],[a],Lsetunion([a],[a],L).).

L = [a] ;L = [a] ;

L = [a, a] ;L = [a, a] ;

NoNo

Here is a

problem

Page 142: AI 08226 Prolog (PROgramming in LOGic)

142

So Use CUT - Set UNION with cut

setunionsetunion( [ ], X, X).( [ ], X, X).

% Add cut so cannot backtrack% Add cut so cannot backtrack

setunionsetunion( [H | T ], L1, L2):( [H | T ], L1, L2):--

member(H, L1),member(H, L1),

!, !,

setunion(Tsetunion(T, L1, L2)., L1, L2).

setunionsetunion( [ H | T ], L1, [ H | L2 ] ):( [ H | T ], L1, [ H | L2 ] ):--

setunionsetunion( T, L1, L2).( T, L1, L2).

��Goal only succeeds the onceGoal only succeeds the once

Page 143: AI 08226 Prolog (PROgramming in LOGic)

143

Testing setunion with The CUT??-- setunion([a],[],Lsetunion([a],[],L).).

L = [a] ;L = [a] ;

NoNo

??-- setunion([a],[a],Lsetunion([a],[a],L).).

L = [a] ;L = [a] ;

NoNo

??-- setunion([bsetunion([b, a],[a, b],L)., a],[a, b],L).

L = [a, b] ;L = [a, b] ;

NoNo

??-- setunion([bsetunion([b, a],[a, b, c, d],L)., a],[a, b, c, d],L).

L = [a, b, c, d] L = [a, b, c, d]

YesYes

Page 144: AI 08226 Prolog (PROgramming in LOGic)

144

Set UNION using not

setunionsetunion( [ ], X, X).( [ ], X, X).

setunionsetunion( [ H | T ], L1, [ H | L2 ] ):( [ H | T ], L1, [ H | L2 ] ):--

not(member(H, L1)),not(member(H, L1)),

setunionsetunion( T, L1, L2).( T, L1, L2).

setunionsetunion( [_H | T ], L1, L2):( [_H | T ], L1, L2):--

setunion(Tsetunion(T, L1, L2)., L1, L2).

��Goal succeeds just the onceGoal succeeds just the once

��??-- setunion([asetunion([a, b, c], [a, d, e], L)., b, c], [a, d, e], L).

L = [b, c, a, d, e] ;L = [b, c, a, d, e] ;

NoNo

Page 145: AI 08226 Prolog (PROgramming in LOGic)

145

Set Intersection using not

�� Set intersection Set intersection -- sets can be represented as listssets can be represented as lists

��{ a, b, c, d } { a, b, c, d } ∩∩∩∩∩∩∩∩ { c, d, e }{ c, d, e } ⇒⇒⇒⇒⇒⇒⇒⇒ { c, d }{ c, d }

intersect( [ ], X, [ ]).intersect( [ ], X, [ ]).

intersect( [H | T ], L1, [ H | L2 ] ):intersect( [H | T ], L1, [ H | L2 ] ):--

member(H, L1), delete(L1, H, L3),member(H, L1), delete(L1, H, L3),

intersect(T, L3, L2).intersect(T, L3, L2).

intersect( [ H | T ], L1, L2 ):intersect( [ H | T ], L1, L2 ):--

not(member(H, L1)), intersect( T, L1, L2).not(member(H, L1)), intersect( T, L1, L2).

��??-- intersect([a, b, c], [a, c, d, e], L).intersect([a, b, c], [a, c, d, e], L).

L = [a, c] ;L = [a, c] ;

NoNo

Page 146: AI 08226 Prolog (PROgramming in LOGic)

146

Set Difference using not

�� Set intersection Set intersection -- sets can be represented as listssets can be represented as lists

��{ a, b, c, d } { a, b, c, d } ⊗⊗⊗⊗⊗⊗⊗⊗ { c, d, e }{ c, d, e } ⇒⇒⇒⇒⇒⇒⇒⇒ { a, b, e }{ a, b, e }

difference( [ ], X, X).difference( [ ], X, X).

difference( [H | T ], L1, L2 ):difference( [H | T ], L1, L2 ):--

member(H, L1), delete(L1, H, L3),member(H, L1), delete(L1, H, L3),

difference(T, L3, L2).difference(T, L3, L2).

difference( [ H | T ], L1, [H | L2] ):difference( [ H | T ], L1, [H | L2] ):--

not member(H, L1), difference( T, L1, L2).not member(H, L1), difference( T, L1, L2).

��??-- difference([a, b, c], [a, c, d, e], L).difference([a, b, c], [a, c, d, e], L).

L = [b, d, e] ;L = [b, d, e] ;

NoNo

Page 147: AI 08226 Prolog (PROgramming in LOGic)

147

Generalisation

�� The idea is to The idea is to generalisegeneralise a problem such that its a problem such that its

solution can be formulated recursivelysolution can be formulated recursively

�� GeneralisationGeneralisation of a relation involves the of a relation involves the

introduction of one or more extra argumentsintroduction of one or more extra arguments

�� Paradoxically, for some problems, the Paradoxically, for some problems, the generalisedgeneralised

version of the problem is easier to solveversion of the problem is easier to solve

��See See BratkoBratko and the Eight Queens [pp 103]and the Eight Queens [pp 103]

�� Add constraints on general problem so it becomesAdd constraints on general problem so it becomes

�� The original problemThe original problem

Page 148: AI 08226 Prolog (PROgramming in LOGic)

148

Structuralisation

�� What are the objects and relations of the problemWhat are the objects and relations of the problem

�� Try drawing figures of the problem or aspects of it Try drawing figures of the problem or aspects of it

��These can map onto semantic networksThese can map onto semantic networks

��Semantic networks can map onto logic and then prologSemantic networks can map onto logic and then prolog

�� As prolog is logic based As prolog is logic based

��So try and represent them using predicate logicSo try and represent them using predicate logic

��Where this breaks down Where this breaks down analyseanalyse whywhy

�� Is a more trivial or general case of the problem easier?Is a more trivial or general case of the problem easier?

��Solve that and modify solution to fitSolve that and modify solution to fit

��Do we need lists Do we need lists -- if so what formif so what form

��What alternatives are?What alternatives are?

Page 149: AI 08226 Prolog (PROgramming in LOGic)

149

Example of structuralisation

�� Consider GO boardConsider GO board

�� How to represent it?How to represent it?

��predicates or listspredicates or lists

�� Predicates of formPredicates of form

��grid(X,Y, Color)grid(X,Y, Color)

�� or List of form or List of form

�� [1[1--11--grey, 1grey, 1--22--white | Tail]white | Tail]

�� What are the benefitsWhat are the benefits

��Try running a small board of 5 by 5 for bothTry running a small board of 5 by 5 for both

��What are the benefits of either representation?What are the benefits of either representation?

Page 150: AI 08226 Prolog (PROgramming in LOGic)

150

Using Pictures

�� Graphical representations may help in the Graphical representations may help in the

perception of some essential relations and perception of some essential relations and

qualities of the problemqualities of the problem

�� Problems can be illustrated by Problems can be illustrated by

��nodes denoting objectsnodes denoting objects

��with connections between nodes representing relationswith connections between nodes representing relations

�� Structured data objects in Prolog can be pictured Structured data objects in Prolog can be pictured

as treesas trees

�� Declarative nature of Prolog facilitates the Declarative nature of Prolog facilitates the

translation of pictorial representations into prolog translation of pictorial representations into prolog

Code Code -- see lectures on semantic networkssee lectures on semantic networks

Page 151: AI 08226 Prolog (PROgramming in LOGic)

151

Some rules of good Prolog style

�� Program clauses should be shortProgram clauses should be short

�� Procedures should be shortProcedures should be short

�� Mnemonic names should be usedMnemonic names should be used

�� Layout is importantLayout is important

��Use space, blank lines and indentationUse space, blank lines and indentation

�� The cut operator should be used with careThe cut operator should be used with care

��better avoidedbetter avoided

�� The not procedure can sometimes lead to The not procedure can sometimes lead to

surprising behavior surprising behavior -- but preferable to cutbut preferable to cut

�� The use of a semiThe use of a semi--colon may obscure the meaningcolon may obscure the meaning

Page 152: AI 08226 Prolog (PROgramming in LOGic)

152

merge - bad style

merge1(List1, List2, List3):merge1(List1, List2, List3):--

List1=[ ], !, List1=[ ], !,

List3=List2;List3=List2; % 1st list empty% 1st list empty

List2=[ ], !, List2=[ ], !,

List3=List1;List3=List1; % 2nd list empty% 2nd list empty

List1=[X|List4],List1=[X|List4],

List2=[Y|List5],List2=[Y|List5],

(X<Y, !, Z=X, merge1(List4,List2, List6);(X<Y, !, Z=X, merge1(List4,List2, List6);

Z=Y, merge1(List1, List5, List6)),Z=Y, merge1(List1, List5, List6)),

List3 = [Z|List6].List3 = [Z|List6].

Page 153: AI 08226 Prolog (PROgramming in LOGic)

153

merge - better style

merge2([ ], L, L):merge2([ ], L, L):-- !. %prevent redundant solutions!. %prevent redundant solutions

merge2(L, [ ], L).merge2(L, [ ], L). % boundary cases% boundary cases

% following clause does ordering test% following clause does ordering test

merge2([H1|Rest1],[H2|Rest2],[H1|Rest3]):merge2([H1|Rest1],[H2|Rest2],[H1|Rest3]):--

H1 < H2, !, H1 < H2, !, %prevent backtracking%prevent backtracking

merge2(Rest1, [H2|Rest2], Rest3).merge2(Rest1, [H2|Rest2], Rest3).

% No ordering test needed on this clause% No ordering test needed on this clause

merge2(List1,[H|Rest2],[H|Rest3]):merge2(List1,[H|Rest2],[H|Rest3]):--

merge2(List1, Rest2, Rest3).merge2(List1, Rest2, Rest3).

Page 154: AI 08226 Prolog (PROgramming in LOGic)

154

Debugging

�� Prolog provides a special debugging aid for Prolog provides a special debugging aid for

tracing a goaltracing a goal

�� Tracing is activated using the predicate Tracing is activated using the predicate tracetrace

��displays useful information during executiondisplays useful information during execution

�� Entry infoEntry info: predicate name and values of : predicate name and values of argsargs

�� Exit infoExit info::

�� if success the value of arguments that satisfy goalif success the value of arguments that satisfy goal

��otherwise an indication of failureotherwise an indication of failure

�� ReRe--entry info:entry info:

�� invocation of the same goal caused by backtrackinginvocation of the same goal caused by backtracking

Page 155: AI 08226 Prolog (PROgramming in LOGic)

155

�� ??-- trace, merge2([1,2],[1],L).trace, merge2([1,2],[1],L).

�� Call: ( 8) merge2([1, 2], [1], _G266) ? creepCall: ( 8) merge2([1, 2], [1], _G266) ? creep

�� Call: ( 9) 1<1 ? creepCall: ( 9) 1<1 ? creep

�� Fail: ( 9) 1<1 ? creepFail: ( 9) 1<1 ? creep

�� Redo: ( 8) merge2([1, 2], [1], _G266) ? creepRedo: ( 8) merge2([1, 2], [1], _G266) ? creep

�� Call: ( 9) merge2([1, 2], [], _G383) ? creepCall: ( 9) merge2([1, 2], [], _G383) ? creep

�� Exit: ( 9) merge2([1, 2], [], [1, 2]) ? creepExit: ( 9) merge2([1, 2], [], [1, 2]) ? creep

�� Exit: ( 8) merge2([1, 2], [1], [1, 1, 2]) ? creepExit: ( 8) merge2([1, 2], [1], [1, 1, 2]) ? creep

�� L = [1, 1, 2] L = [1, 1, 2]

�� YesYes

Page 156: AI 08226 Prolog (PROgramming in LOGic)

156

Sorting lists - Bubble Sort

�� bubblesort(Listbubblesort(List, Sorted, Sorted).).

��Assume ordering relation Assume ordering relation gt(X,Ygt(X,Y))

��meaning meaning XX is greater than is greater than YY

�� IfIf X X andand Y Y are numbers then could useare numbers then could use

�� gt(Xgt(X, Y) :, Y) :-- X > Y.X > Y.

�� find two adjacent elements find two adjacent elements XX, , YY in in ListList

��such that such that gt(Xgt(X, Y), Y) -- swap swap XX and and YY in in ListList to get to get List1List1

��sort sort List1List1

�� if there no pair if there no pair XX, Y such that , Y such that gt(X,Ygt(X,Y))

�� then then ListList is is SortedSorted

Page 157: AI 08226 Prolog (PROgramming in LOGic)

157

Bubble Sort

bubblesort(Listbubblesort(List, Sorted):, Sorted):--

swap(List, List1), !, swap(List, List1), !, % A Useful Swap?% A Useful Swap?

bubblesort(List1, Sorted).bubblesort(List1, Sorted).

bubblesort(Sortedbubblesort(Sorted, Sorted)., Sorted). % Boundary% Boundary

swap( [ X, Y | Rest], [Y, X | Rest] ):swap( [ X, Y | Rest], [Y, X | Rest] ):--

gt(Xgt(X, Y)., Y).

swap( [ Z | Rest1 ], [ Z | Rest2 ]):swap( [ Z | Rest1 ], [ Z | Rest2 ]):--

swap(Rest1, Rest2).swap(Rest1, Rest2).

Page 158: AI 08226 Prolog (PROgramming in LOGic)

158

Insert Sort�� To sort a nonTo sort a non--empty list, L = [H | T]empty list, L = [H | T]

��sort the tail T of Lsort the tail T of L

�� Insert the head H into a position in the sorted tail such Insert the head H into a position in the sorted tail such

that the result is sortedthat the result is sorted

insertsortinsertsort( [ ], [ ] ).( [ ], [ ] ).

insertsortinsertsort( [ X | T ], Sorted ):( [ X | T ], Sorted ):--

insertsortinsertsort( T, ( T, SortedTSortedT ),), % sort tail% sort tail

insert(X, insert(X, SortedTSortedT, Sorted )., Sorted ). % insert and sort% insert and sort

insert(X, [Y | Sorted], [ Y | Sorted1 ]):insert(X, [Y | Sorted], [ Y | Sorted1 ]):-- gt(Xgt(X, Y), !,, Y), !,

insert(X, Sorted, Sorted1).insert(X, Sorted, Sorted1).

insert( X, Sorted, [ X | Sorted ]).insert( X, Sorted, [ X | Sorted ]).

Page 159: AI 08226 Prolog (PROgramming in LOGic)

159

Running swap.pl - with time/1

�� ??-- bubblesort([1, 3, 9, 0, 6, 8, 4, 5, 7, 2],S).bubblesort([1, 3, 9, 0, 6, 8, 4, 5, 7, 2],S).

S = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] S = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

�� ??-- insertsort([1, 3, 9, 0, 6, 8, 4, 5, 7, 2],S).insertsort([1, 3, 9, 0, 6, 8, 4, 5, 7, 2],S).

S = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] S = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

�� ??-- time(bubblesort([1, 3, 9, 0, 6, 8, 4, 5, 7, 2],S)).time(bubblesort([1, 3, 9, 0, 6, 8, 4, 5, 7, 2],S)).

556 inferences in 0.00 seconds (Infinite Lips)556 inferences in 0.00 seconds (Infinite Lips)

S = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] S = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

�� ??-- time(insertsort([1, 3, 9, 0, 6, 8, 4, 5, 7, 2],S)).time(insertsort([1, 3, 9, 0, 6, 8, 4, 5, 7, 2],S)).

107 inferences in 0.00 seconds (Infinite Lips)107 inferences in 0.00 seconds (Infinite Lips)

S = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]S = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Page 160: AI 08226 Prolog (PROgramming in LOGic)

160

Running the merges with time/1

�� ??-- time(merge1([0, 2, 4, 6, 8], [1, 3, 5, 7, 9], L)).time(merge1([0, 2, 4, 6, 8], [1, 3, 5, 7, 9], L)).

131 inferences in 0.00 seconds (Infinite Lips)131 inferences in 0.00 seconds (Infinite Lips)

L = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] L = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

YesYes

�� ??-- time(merge2([0, 2, 4, 6, 8], [1, 3, 5, 7, 9], L)).time(merge2([0, 2, 4, 6, 8], [1, 3, 5, 7, 9], L)).

25 inferences in 0.00 seconds (Infinite Lips)25 inferences in 0.00 seconds (Infinite Lips)

L = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] L = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

YesYes

Page 161: AI 08226 Prolog (PROgramming in LOGic)

161

Manipulating Characters�� atom_chars/2atom_chars/2

��Convert between atom and list of ASCII valuesConvert between atom and list of ASCII values

�� atom_char/2atom_char/2

��Convert between atom and ASCII valueConvert between atom and ASCII value

�� name/2name/2

��Convert between atom and list of ASCII charactersConvert between atom and list of ASCII characters

�� string_to_list/2string_to_list/2

��Conversion between string and list of ASCIIConversion between string and list of ASCII

�� put/1put/1 places ASII value on output streamplaces ASII value on output stream

�� get0/1get0/1 Read next characterRead next character

�� get/1 Read first nonget/1 Read first non--blank characterblank character

Page 162: AI 08226 Prolog (PROgramming in LOGic)

162

Manipulating Characters�� atom_chars/2atom_chars/2

��??-- atom_chars(atom, Chars).atom_chars(atom, Chars).

Chars = [97, 116, 111, 109]Chars = [97, 116, 111, 109]

��??-- atom_chars(Atom, atom_chars(Atom, ““CharsChars””).).

Atom = Atom = ‘‘CharsChars’’

�� atom_char/2atom_char/2

��??-- atom_char(a, Char).atom_char(a, Char).

Char = 97 Char = 97

��??-- atom_char(Atom, 97).atom_char(Atom, 97).

Atom = aAtom = a

Page 163: AI 08226 Prolog (PROgramming in LOGic)

163

Manipulating Characters

�� name/2name/2

��??-- name(atom, List).name(atom, List).

Chars = [97, 116, 111, 109] Chars = [97, 116, 111, 109]

��??-- name(Atom, "name(Atom, "abcabc").").

Atom = Atom = abcabc

�� string_to_list/2string_to_list/2

��??-- string_to_list('Atom',L).string_to_list('Atom',L).

L = [65, 116, 111, 109] L = [65, 116, 111, 109]

��??-- string_to_list(String, "string_to_list(String, "StringOfAsciiStringOfAscii").").

String = "String = "StringOfAsciiStringOfAscii" "

Page 164: AI 08226 Prolog (PROgramming in LOGic)

164

Manipulating Characters��??-- string_to_list(String, [65, 111]), atom(String).string_to_list(String, [65, 111]), atom(String).

NoNo

��??-- String = 'atom', string_to_list(S, List), atom(S).String = 'atom', string_to_list(S, List), atom(S).

S = atomS = atom

List = [97, 116, 111, 109] List = [97, 116, 111, 109]

YesYes

��??-- string_to_list(String, [65, 111]), string_to_list(String, [65, 111]),

string_to_atom(String,Atom), atom(Atom).string_to_atom(String,Atom), atom(Atom).

String = "String = "AoAo""

Atom = 'Atom = 'AoAo' '

YesYes

Page 165: AI 08226 Prolog (PROgramming in LOGic)

165

Manipulating Characters

�� Input and Output of ASCII valuesInput and Output of ASCII values

��??-- put(65), put(66), put(67).put(65), put(66), put(67).

ABCABC

��??-- get0(C).get0(C). ??-- get0(C), get0(A).get0(C), get0(A).

: : aa :: asas

C = 97 C = 97 C = 97C = 97

A = 115A = 115

��??-- get(C).get(C).

: a: a

C = 97 C = 97

Page 166: AI 08226 Prolog (PROgramming in LOGic)

166

Testing the Type of Terms

�� var/1var/1 Type check for unbound variableType check for unbound variable

�� nonvar/1nonvar/1 Type check for bound termType check for bound term

�� ground/1ground/1 Verify term holds no unbound variablesVerify term holds no unbound variables

�� atom/1atom/1 Type check for an atomType check for an atom

�� atomic/1atomic/1 Type check for primitiveType check for primitive

�� integer/1integer/1 Type check for integerType check for integer

�� number/1number/1 Type check for integer or floatType check for integer or float

�� float/1float/1 Type check for a floating point numberType check for a floating point number

Page 167: AI 08226 Prolog (PROgramming in LOGic)

167��??-- var(Xvar(X), X = 2.), X = 2. ??-- nonvar(Xnonvar(X), X = 2.), X = 2.

X = 2 X = 2 NoNo

YesYes

��??-- X = 2, X = 2, var(Xvar(X).). ??-- X = 2, X = 2, nonvar(Xnonvar(X) )

NoNo X =2X =2

YesYes

��??-- integer(X), X =2. integer(X), X =2. ??-- X = 2, integer(X).X = 2, integer(X).

NoNo X = 2X = 2

YesYes

��??-- X = 2, atomic(X). X = 2, atomic(X). ??-- X = 2, atom(X).X = 2, atom(X).

X = 2 X = 2 NoNo

YesYes ??-- X = a, atom(X).X = a, atom(X).

X = a X = a YesYes

Page 168: AI 08226 Prolog (PROgramming in LOGic)

168�� ??-- var(Xvar(X), X = 2.), X = 2.

X = 2X = 2

YesYes

�� ??-- X = 2, X = 2, var(Xvar(X).).

NoNo

�� ??-- nonvar(Xnonvar(X), X = 2), X = 2

NoNo

�� ??-- X = 2, X = 2, nonvar(Xnonvar(X).).

X = 2.X = 2.

YesYes

�� ??-- integer(X), X =2.integer(X), X =2.

NoNo

�� ??-- X = 2, integer(X).X = 2, integer(X).

X =2X =2

YesYes

�� ??-- X = 2, atom(X).X = 2, atom(X).

NoNo

�� ??-- X = a, atom(X).X = a, atom(X).

X = aX = a

YesYes

�� ??-- atom(X), X =a.atom(X), X =a.

NoNo

�� ??-- X = 2, atomic(X).X = 2, atomic(X).

X = 2X = 2

YesYes

Page 169: AI 08226 Prolog (PROgramming in LOGic)

169

What does the following code do?

�� enigma( [ ] ):enigma( [ ] ):-- write( write( ‘‘..’’), ), nlnl..

�� enigma( [ L | Lt ]):enigma( [ L | Lt ]):-- write(write(‘‘ ‘‘),),

name(L, [ Z | name(L, [ Z | ZtZt ]),]),

Y is Z Y is Z -- 32,32,

name(X, [ Y | name(X, [ Y | ZtZt ]),]),

write(X),write(X),

enigma( Lt ).enigma( Lt ).

Page 170: AI 08226 Prolog (PROgramming in LOGic)

170

Comments

�� % This is a comment % This is a comment

�� /* This is another Comment *//* This is another Comment */

�� LayoutLayout

% File:% File: mycomments.plmycomments.pl

% author:% author: fredfred platocratesplatocrates

% date:% date: 04:15am 10 04:15am 10 JunusJunus 350BC350BC

% updated:% updated: Thursday, April 13, 2000Thursday, April 13, 2000

% purpose:% purpose: Header for basic comments fileHeader for basic comments file

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% go/0 this starts the program which exits prolog% go/0 this starts the program which exits prolog

go:go:-- halt.halt.

Page 171: AI 08226 Prolog (PROgramming in LOGic)

171

Getting a listing

�� listing/0 lists all the loaded code listing/0 lists all the loaded code

��some of which is not yourssome of which is not yours

d:/LECTURES/AI1/PROLOG/MYCOMM~1.PL d:/LECTURES/AI1/PROLOG/MYCOMM~1.PL

compiled, 0.00 sec, 640 bytes.compiled, 0.00 sec, 640 bytes.

??-- listing.listing.

'$user_query'(1, []) :'$user_query'(1, []) :--

listing.listing.

go :go :--

halt.halt.

% Foreign: window_title/2% Foreign: window_title/2

YesYes

Page 172: AI 08226 Prolog (PROgramming in LOGic)

172

Getting a listing

�� listing/1 lists all the predicate clauses that matchlisting/1 lists all the predicate clauses that match

??-- listing(merge2).listing(merge2).

merge2([], A, A) :merge2([], A, A) :-- !.!.

merge2(A, [], A).merge2(A, [], A).

merge2([A|B], [C|D], [A|E]) :merge2([A|B], [C|D], [A|E]) :--

A<C, !,A<C, !,

merge2(B, [C|D], E).merge2(B, [C|D], E).

merge2(A, [B|C], [B|D]) :merge2(A, [B|C], [B|D]) :--

merge2(A, C, D).merge2(A, C, D).

YesYes