Presentation is loading. Please wait.

Presentation is loading. Please wait.

CSI 2115, Prolog, page 1 Logic programming in Prolog A little background Prolog warm-up SWI Prolog A session with Prolog Two interpretations A bit of terminology.

Similar presentations


Presentation on theme: "CSI 2115, Prolog, page 1 Logic programming in Prolog A little background Prolog warm-up SWI Prolog A session with Prolog Two interpretations A bit of terminology."— Presentation transcript:

1 CSI 2115, Prolog, page 1 Logic programming in Prolog A little background Prolog warm-up SWI Prolog A session with Prolog Two interpretations A bit of terminology A note on semantics Arithmetics Compound objects Lists Non-determinism Last words Reading: chapter 16 (not great), these notes, tutorials on the Web.

2 CSI 2115, Prolog, page 2 A little background Prolog was invented in 1970, first implemented in 1972, first implemented efficiently in Excellent commercial- strength implementations have existed since early 1980s. After 30 years, Prolog has been unmatched as an unusually powerful language for a fairly wide range of applications (including software prototyping and runnable specifications) but it is amazingly underappreciated. People do not even know that Prolog is faster than Java when applied in the right way, and that software production can be an order of magnitude faster in this very high level programming language. (Section 2.13 of the textbook says a lot of nonsense; ignore it.)

3 CSI 2115, Prolog, page 3 Prolog warm-up (a)People who catch colds should avoid open swimming pools in winter. (b)Everybody who doesn't wear a hat in winter catches colds. (c)Everybody who doesn't wear a hat at all doesn't wear a hat in winter. (d)Jacky never wears a hat. (e)What should Jacky avoid? [1]If Jacky catchs colds then Jacky should avoid open swimming pools in winter. [2]If Jacky doesn't wear a hat in winter then Jacky catches cold. [3]If Jacky never wears a hat then Jacky doesn't wear a hat in winter. [4]Obviously Jacky never wears a hat. By [4], [3], [2], [1], Jacky should avoid open swimming pools in winter.

4 CSI 2115, Prolog, page 4 Prolog warm-up (2) Let's translate this into Prolog. % (a) [text after % is a comment] avoid( Person, swimming_pools_in_winter ) :- catch_colds( Person ). /* (b) [a bracketed comment] */ catch_colds( Person ) :- no_hat_in_winter( Person ). % (c) no_hat_in_winter( Person ) :- no_hat_at_all( Person ). % (d) no_hat_at_all( jacky ). Now, we ask Prolog the question: % (e) ?- avoid( jacky, What ). What = swimming_pools_in_winter Yes

5 CSI 2115, Prolog, page 5 Prolog warm-up (3) Another example (f)A prime number N is a number whose set of divisors contains only 1 and N. (g)The set of divisors of a number N is the set of numbers in the range 1.. N which divide N exactly. Question (h)Is 19 a prime number? is 21? A slightly more efficient algorithm (i)2 is a prime number. (j)A number N greater than 2 is prime if it is odd and its set of odd divisors contains only 1 and N. (k)The set of odd divisors of an odd number N is the set of numbers in the sequence 1, 3, 5,..., N which divide N exactly.

6 CSI 2115, Prolog, page 6 Prolog warm-up (4) Again, let's translate this into Prolog. % (f) prime( N ) :- divisor_set( N, [1, N] ). % (g) divisor_set( N, DivSet ) :- setof( K, ( in_range( K, 1, N ), N mod K =:= 0 ), DivSet ). continued... =:= is a built-in comparison, one of many setof : built-in

7 CSI 2115, Prolog, page 7 Prolog warm-up (5) Let’s now define a range of values. % (g') two cases are possible in_range( K, K, High ) :- K =< High. in_range( K, Low, High ) :- Low < High, % "is" resembles assignment: Low1 is Low + 1, in_range( K, Low1, High ). Now, the question: % (h) ?- prime( 19 ). Yes ?- prime( 21 ). No... concluded

8 CSI 2115, Prolog, page 8 Prolog warm-up (6) The more efficient version: % (i) prime( 2 ). % (j) prime( N ) :- N mod 2 =:= 1, divisor_set( N, [1, N] ). % (k) divisor_set( N, DivSet ) :- setof( K, ( in_range2( K, 1, N ), N mod K =:= 0 ), DivSet ). continued...

9 CSI 2115, Prolog, page 9 Prolog warm-up (7) % (k') in_range2( K, K, High ) :- K =< High. in_range2( K, Low, High ) :- Low < High, Low1 is Low + 2, in_range2( K, Low1, High ). And the question: % (h) ?- prime( 19 ). Yes ?- prime( 21 ). No... concluded

10 CSI 2115, Prolog, page 10 SWI Prolog {site2}szpak(1)$ alias pl /usr/local/swipl/lib/pl-5.2.8/bin/i686-linux/pl % pl Welcome to SWI-Prolog (Multi-threaded, Version 5.2.8) Copyright (c) University of Amsterdam. SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. Please visit for details. For help, use ?- help(Topic). or ?- apropos(Word). ?- halt. {site2}szpak(2)$ We will work in SWI Prolog, an excellent public- domain implementation for industrial-strength applications. It is installed on site2, SITE’s Linux server. Call ssh to connect to site2. Feel free to get your own copy—for Windows— but submit work tested in Linux. Note that it is donateware.

11 CSI 2115, Prolog, page 11 On-line help {site2}szpak(1)$ pl Welcome to SWI-Prolog [...] For help, use ?- help(Topic). or ?- apropos(Word). ?- apropos(write). put/1 Write a character put/2 Write a character on a stream put_byte/1 Write a byte put_byte/2 Write a byte on a stream put_char/1 Write a character put_char/2 Write a character on a stream put_code/1 Write a character-code put_code/2 Write a character-code on a stream write_term/2 Write term with options write_term/3 Write term with options to stream write_canonical/1 Write a term with quotes, ignore operators write_canonical/2 Write a term with quotes, ignore operators on a stream write/1 Write term write/2 Write term to stream writeq/1 Write term, insert quotes writeq/2 Write term, insert quotes on stream writeln/1 Write term, followed by a newline writef/1 Formatted write writef/2 Formatted write on stream swritef/3 Formatted write on a string swritef/2 Formatted write on a string tty_put/2 Write control string to terminal Section 4-33 "Formatted Write" Section "Writef" Section "An example: defining write/1 in C" Yes ?- help(write). write(+Term) Write Term to the current output, using brackets and operators where appropriate. See current_prolog_flag/2 for controlling floating point output format. write(+Stream, +Term) Write Term to Stream. Yes ?-

12 CSI 2115, Prolog, page 12 A session with Prolog {site2}szpak(1)$ cat bad_habits_1 likes( jim, sandra ). likes( jim, bill ). likes( peggy, sam ). likes( bill, sandra ). drinks( jim, beer ). drinks( peggy, coke ). drinks( bill, juice ). drinks( sam, gin ). smokes( bill ). smokes( sandra ). smokes( sam ). will_dance( jim, peggy ) :- drinks( peggy, coke ). will_dance( bill, sandra ) :- likes( bill, sandra ), drinks( sandra, beer ). will_dance( sam, peggy ) :- likes( peggy, sam ), drinks( sam, gin ), % does not smoke \+ smokes( peggy ).

13 CSI 2115, Prolog, page 13 A session with Prolog (2) {site2}szpak(2)$ pl Welcome to SWI-Prolog (Multi-threaded, Version 5.2.8) [...] ?- [bad_habits_1]. % bad_habits_1 compiled 0.00 sec, 2,056 bytes Yes ?- likes( jim, bill ). Yes ?- drinks( bill, gin ). No ?- will_dance( jim, peggy ). Yes ?- will_dance( bill, sandra ). No ?- will_dance( sam, peggy ). Yes ?- smokes( terry ). No ?- halt. load file

14 CSI 2115, Prolog, page 14 A session with Prolog (3) {site2}szpak(3)$ cat bad_habits_2 likes( jim, sandra ). likes( jim, bill ). likes( peggy, sam ). likes( bill, sandra ). drinks( jim, beer ). drinks( peggy, coke ). drinks( bill, juice ). drinks( sam, gin ). drinks( sandra, beer ) :- drinks( jim, beer ). smokes( bill ). smokes( sandra ). smokes( sam ). will_dance( jim, peggy ) :- drinks( peggy, coke ). will_dance( bill, sandra ) :- likes( bill, sandra ), drinks( sandra, beer ). will_dance( sam, peggy ) :- likes( peggy, sam ), drinks( sam, gin ), % does not smoke \+ smokes( peggy ).

15 CSI 2115, Prolog, page 15 A session with Prolog (4) {site2}szpak(4)$ pl bad_habits_2 % bad_habits_2 compiled 0.00 sec, 2,140 bytes Welcome to SWI-Prolog [...] ?- likes( jim, bill ). Yes ?- drinks( bill, gin ). No ?- will_dance( jim, peggy ). Yes ?- will_dance( bill, sandra ). Yes ?- will_dance( sam, peggy ). Yes ?- smokes( terry ). No ?- halt. load a file was: No

16 CSI 2115, Prolog, page 16 A session with Prolog (5) {site2}szpak(5)$ cat bad_habits_3 likes( jim, sandra ). likes( jim, peggy ). likes( peggy, sam ). likes( bill, sandra ). drinks( jim, beer ). drinks( peggy, coke ). drinks( bill, juice ). drinks( sam, gin ). drinks( sandra, beer ) :- drinks( jim, beer ). smokes( bill ). smokes( sandra ). smokes( sam ). will_dance( jim, peggy ) :- drinks( peggy, coke ). will_dance( bill, sandra ) :- likes( bill, sandra ), drinks( sandra, beer ). will_dance( sam, peggy ) :- likes( peggy, sam ), drinks( sam, gin ), % does not smoke \+ smokes( peggy ).

17 CSI 2115, Prolog, page 17 A session with Prolog (6) {site2}szpak(6)$ pl -f bad_habits_3 % bad_habits_3 compiled 0.00 sec, 2,140 bytes Welcome to SWI-Prolog [...] ?- drinks( Who, gin ). Who = sam ; No ?- likes( jim, Whom ). Whom = sandra ; Whom = peggy ; No ?- will_dance( P1, P2 ). P1 = jim P2 = peggy ; P1 = bill P2 = sandra ; P1 = sam P2 = peggy ; No ?- ^D % halt {site2}szpak(7)$

18 CSI 2115, Prolog, page 18 An interlude Who, Whom, P1, P2 are variables: unknown objects about which we wish to find out more. Numbers in Prolog have the usual syntax, for example 23, , 10e3. Variables are written as identifiers that start with a capital letter or an underscore. Note: a variable can only get its value once -- this will be explained soon. Constants are written as identifiers that start with a small letter, for example sandra, catch_colds, likes. continued...

19 CSI 2115, Prolog, page 19 An interlude (2) Constants can also be symbolic: almost any combination of + - * /. # $ % ^ & ? is valid, for example =:=.:. ::== Finally, a quoted constant is a sequence of any characters in single quotes, for example 'Hello, world!' A single quote must be repeated: 'Isn''t it nice?'... concluded

20 CSI 2115, Prolog, page 20 A session with Prolog (7) {site2}szpak(7)$ cat bad_habits_4 likes( jim, sandra ). likes( jim, peggy ). likes( peggy, sam ). likes( bill, sandra ). drinks( jim, beer ). drinks( peggy, coke ). drinks( bill, juice ). drinks( sam, gin ). drinks( sandra, beer ) :- drinks( jim, beer ). smokes( bill ). smokes( sandra ). smokes( sam ). will_dance( jim, peggy ) :- drinks( peggy, coke ). will_dance( bill, sandra ) :- likes( bill, sandra ), drinks( sandra, beer ). will_dance( sam, peggy ) :- likes( peggy, sam ), drinks( sam, gin ), \+ smokes( peggy ). ill( X ) :- smokes( X ), drinks( X, Y ), alcoholic( Y ). alcoholic( beer ). alcoholic( gin ). variables in rules

21 CSI 2115, Prolog, page 21 A session with Prolog (8) {site2}szpak(8)$ pl -f bad_habits_4 % bad_habits_4 compiled 0.00 sec, 2,596 bytes Welcome to SWI-Prolog [...] ?- ill(Somebody). Somebody = sandra ; Somebody = sam ; No ?- ^D % halt

22 CSI 2115, Prolog, page 22 A session with Prolog (9) {site2}szpak(9)$ cat bad_habits_5 likes( jim, sandra ). likes( jim, peggy ). likes( peggy, sam ). likes( bill, sandra ). drinks( jim, beer ). drinks( peggy, coke ). drinks( bill, juice ). drinks( sam, gin ). drinks( sandra, beer ) :- drinks( jim, beer ). smokes( bill ). smokes( sandra ). smokes( sam ). will_dance( jim, peggy ) :- drinks( peggy, coke ). will_dance( bill, sandra ) :- likes( bill, sandra ), drinks( sandra, beer ). will_dance( sam, peggy ) :- likes( peggy, sam ), drinks( sam, gin ), \+ smokes( peggy ). ill( X ) :- smokes( X ), drinks( X, Y ), alcoholic( Y ). alcoholic( beer ). alcoholic( gin ). will_talk( peggy, M ) :- man( M ), non_drinker( M ). non_drinker( M ) :- drinks( M, B ), \+ alcoholic( B ). non_drinker( M ) :- \+ drinks( M, _B ). man( jim ). man( bill ). man( sam ).

23 CSI 2115, Prolog, page 23 A session with Prolog (10) {site2}szpak(10)$ pl -f bad_habits_5 % bad_habits_5 compiled [...] ?- will_talk( peggy, ThatGuy ). ThatGuy = bill ; No ?- will_talk( peggy, A_man ), | likes( peggy, A_man ). No ?- drinks( M, D ), man( M ). M = jim D = beer ; M = bill D = juice ; M = sam D = gin ; No ?- man( M ), drinks( M, D ). M = jim D = beer ; M = bill D = juice ; M = sam D = gin ; No continued...

24 CSI 2115, Prolog, page 24 A session with Prolog (11)... concluded ?- drinks( M, D ), | \+ man( M ). M = peggy D = coke ; M = sandra D = beer ; No ?- \+ man( M ), | drinks( M, D ). No ?- ^D % halt Variables are local in a fact, rule or query. There are no global variables. The first occurrence of a variable must not be "under negation".

25 CSI 2115, Prolog, page 25 A session with Prolog (12) {site2}szpak(11)$ cat family father( anthony, james ). father( john, paul ). father( luke, peter ). father( matthew, mark ). father( peter, john ). father( peter, matthew ). father( thomas, anthony ). father( thomas, luke ). grandfather( X, Y ) :- father( X, Z ), father( Z, Y ). greatGrandfather( X, Y ) :- father( X, Z ), grandfather( Z, Y ). greatGreatGrandfather( X, Y ) :- father( X, Z ), greatGrandfather( Z, Y ). ancestor( X, Y ) :- father( X, Y ). ancestor( X, Y ) :- father( X, Z ), ancestor( Z, Y ). recursion

26 CSI 2115, Prolog, page 26 A session with Prolog (13) {site2}szpak(12)$ pl -f family % family compiled 0.00 sec, 2,060 bytes Welcome to SWI-Prolog [...] ?- ancestor( peter, mark ). Yes ?- ancestor( X, john ). X = peter ; X = luke ; X = thomas ; No ?- ancestor( matthew, X ). X = mark ; No ?- ancestor( X, Y ) answers ?- ^D % halt

27 CSI 2115, Prolog, page 27 Two interpretations The definition of ancestor can be read like this: Your father is your ancestor, and the father of your ancestor is your ancestor, too. This is an example of the declarative (or static, or logical) interpretation of Prolog definitions. Queries, however, are used to find answers, not only to confirm truths recorded in the Prolog database. Finding is necessarily dynamic, so we need another interpretation. The procedural (or imperative, or control) interpretation of Prolog facts and rules focuses on the process of finding answers: To find an ancestor of Y, find his father; or else, take his father (call him Z) and find Z's ancestor.

28 CSI 2115, Prolog, page 28 Two interpretations (2) This is the description of a procedure with two variants, one of which is chosen for execution. The procedure's name is ancestor, and it has two parameters. The body of the second variant consists of two procedure calls: first, father with 2 parameters; next, ancestor with 2 parameters. For consistency, a fact is treated as a procedure with an empty body.

29 CSI 2115, Prolog, page 29 Two interpretations (3) Another example: ill( X ) :- smokes( X ), drinks( X, Y ), alcoholic( Y ). To find an ill person, find somebody who smokes, then find a drink which he drinks, and finally check whether this drink is alcoholic. This procedure has only one variant, and its body contains three calls.

30 CSI 2115, Prolog, page 30 Two interpretations (4) Prolog has no conditional statements and no iterations. The only operations allowed in the body of a procedure are other procedure calls—and this is quite sufficient! Note that the order of conditions is important for the procedural reading: ill( X ) :- alcoholic( Y ), smokes( X ), drinks( X, Y ). To find an ill person, find an alcoholic drink, then find a smoker, and finally check whether this smoker drinks this drink.

31 CSI 2115, Prolog, page 31 Arithmetics {site2}szpak(13)$ cat q_eqn % A*X*X + B*X + C = 0, % A cannot be zero. q_eqn( A, _B, _C, none, none ) :- A =:= 0. q_eqn( A, B, C, X1, X2 ) :- A =\= 0, Delta is B*B - 4.0*A*C, q_eqn_( Delta, A, B, X1, X2 ). % q_eqn_ are auxiliary rules q_eqn_( Delta, _A, _B, imag, imag ) :- Delta < 0. % two real solutions, may be identical q_eqn_( Delta, A, B, X1, X2 ) :- Delta >= 0, SqrtDelta is sqrt( Delta ), X1 is (-B-SqrtDelta ) / (2.0*A ), X2 is (-B+SqrtDelta ) / (2.0*A ). % data validation: % A, B, C should be numbers q_EQN( A, B, C, X1, X2 ) :- number( A ), number( B ), number( C ), q_eqn( A, B, C, X1, X2 ). a built-in test, one of many

32 CSI 2115, Prolog, page 32 Arithmetics (2) {site2}szpak(14)$ pl -f q_eqn % q_eqn compiled [...] ?- q_eqn( 8, -6, -35, X, Y ). X = Y = 2.5 Yes ?- q_eqn( 8, -6, 35, X, Y ). X = imag Y = imag Yes ?- q_eqn( 0, -6, -35, X, Y ). X = none Y = none Yes ?- q_EQN( 8, -6, abc, X, Y ). No ?- q_eqn( 8, -6, abc, X, Y ). ERROR: Arithmetic: `abc/0’ is not a function ^ Exception: (8) _G260 is-6* *8*abc ? ?- ^D % halt

33 CSI 2115, Prolog, page 33 Arithmetics (3) {site2}szpak(15)$ cat pow % pow( X, Y, Z ) means X ^ Y = Z % X^1 = X pow( X, 1, X ). % for Y > 1, X^Y = X * X^(Y-1) pow( X, Y, Z ) :- Y > 1, Y1 is Y - 1, pow( X, Y1, Z1 ), Z is X * Z1. {site2}szpak(16)$ pl -f pow % pow compiled [...] ?- pow( 7, 3, P ). P = 343 Yes ?- pow( 7, 3, 345 ). No ?- ^D % halt

34 CSI 2115, Prolog, page 34 Compound objects Constants, including numbers, are simple objects. They have no internal structure. We do not declare constants: we use them whenever we need them. We also need compound objects: ordered collections of simpler objects that are in some relationship. Examples: two sides of a rectangle, such as 19 by 24, the time in hours and minutes, such as 19:24. Since the pair (19, 24) may represent a rectangle or a time, we distinguish them by naming the relationship: rectangle( 19, 24 ) time_of_day( 19, 24 )

35 CSI 2115, Prolog, page 35 Compound objects (2) We can also represent the time with seconds: time_of_day( 19, 24, 37 ) This is a different object, but Prolog easily distinguishes these two representations of time. The name is the same, but the arity is not. We have time_of_day/2 (two components), time_of_day/3 (three components). Again, we do not need to declare compound objects. The name of a compound object (and the name of the relationship between components) is called a functor. A components, called an argument, can be any object.

36 CSI 2115, Prolog, page 36 Compound objects (3) Example: customer( name( jim, white ), address( street( 17, main ), city( bytown, ontario ) ) ) A compound object is incompletely specified if it contains variables — unknown components. An example: customer( X, address( street( 17, main ), city( bytown, ontario ) ) ) "Any customer who lives at 17 Main, Bytown, Ontario."

37 CSI 2115, Prolog, page 37 Compound objects (4) customer( name( X, white ), address( street( Y, main ), city( Z, ontario ) ) ) "Any customer by the name of White who lives at Main, any town, Ontario.” A variable may appear more than once. For example, rectangle( X, X ) represents a square!

38 CSI 2115, Prolog, page 38 Compound objects (5) {site2}szpak(17)$ cat empl % empl( X, Y, Z ) means "employee X works % for department Y and earns Z dollars" empl( name( john, smith ), dept( appliances, 1 ), 350 ). empl( name( nancy, brown ), dept( appliances, 2 ), 375 ). empl( name( peggy, lee ), dept( cosmetics, 1 ), 410 ). empl( name( tania, smith ), dept( shoes, 1 ), 325 ). empl( name( fran, jones ), dept( appliances, 2 ), 380 ). empl( name( carrie, mcrae ), dept( toys, 1 ), 350 ). continued...

39 CSI 2115, Prolog, page 39 Compound objects (6) {site2}szpak(18)$ pl -f empl % empl compiled [...] ?- empl( name( _, smith ), X, _ ). X = dept(appliances, 1) ; X = dept(shoes, 1) ; No ?- empl( name( First, Last ), dept( appliances, _ ), _ ). First = john Last = smith ; First = nancy Last = brown ; First = fran Last = jones ; No ?- empl( Name, _, D ), D > 375. Name = name(peggy, lee) D = 410 ; Name = name(fran, jones) D = 380 ; No ?- ^D % halt... concluded _ is a “sink”, a don’t care variable

40 CSI 2115, Prolog, page 40 Lists Lists in Prolog are normal compound objects. By convention, we use the functor. /2 (dot with two arguments) to build lists. We treat the structure.(p,.(q,.(r, [] ) ) ) as a representation of the 3-element sequence p, q, r. [] is the empty list. List are so useful that a special notation has been introduced for them. A list is a sequence of objects in square brackets, separated by commas: [ p, q, r ] is the same as.(p,.(q,.(r, [])))

41 CSI 2115, Prolog, page 41 Lists (2) [ 1, 3, 8, 16, 23, 34 ] [ [ sam, jimmy ], [ peggy, sally ] ] [ X, Y ] A list may contain differently shaped objects. This is a correct, even if a bit useless, Prolog list: [ rectangle(78, 78), name(fran, jones), street(17, main ), 'Hello, world!' ] Finally, the notation [ Hd | Tl ] means a list with a head Hd and a tail Tl, or.(Hd, Tl).

42 CSI 2115, Prolog, page 42 Lists (3) Let us define the relation between a list and its length. The length of an empty list is 0: length_( [], 0 ). The length of a non-empty list is 1 more than the length of its tail: length_( [ _H | T ], Len ) :- length_( T, Len1 ), Len is Len By the way, length is built into most Prolog systems and need not (cannot in SWI Prolog!) be defined by the user.

43 CSI 2115, Prolog, page 43 Lists (4) Now, let us pick an element of a list by position. The first element of a non-empty list is its head: nth( 1, [Hd | _Tl], Hd ). Element number N > 0 of a non-empty list is element number N-1 of its tail: nth( N, [_ | Tl], NthElem ) :- N > 1, N1 is N - 1, nth( N1, Tl, NthElem ).

44 CSI 2115, Prolog, page 44 Non-determinism Prolog can produce multiple answers to a query, one by one (see slides 17, 21, 23, 24, 26, 39). When we type a semicolon after getting query results, Prolog looks for another answer. We will now show how this property — called non-determinism — helps program in a very general way. Let us define the membership relation between a list and its element. The head of a non-empty list is its element: element( Hd, [Hd | _Tl] ). The same element can be found further on the list: element( Elem, [ _Hd | Tl ] ) :- element( Elem, Tl ). By the way, member is the built-in version in SWI Prolog and in many other Prolog systems.

45 CSI 2115, Prolog, page 45 Non-determinism (2) The procedural interpretation, the base case To find an element X of a given list, take this list's head as X. or To find a list with a given element X, construct a list with X as its head. The recursive case To find an element X of a given list, make X an element of this list's tail. or To find a list with a given element X, construct a list with anything as its head and X somewhere in its tail.

46 CSI 2115, Prolog, page 46 Non-determinism (3) ?- element( 2, [1, 2, 3] ). Yes ?- element( X, [1, 2] ). X = 1 ; X = 2 ; No ?- element( 3, [A, B] ). A = 3 B = _G160 ; A = _G157 B = 3 ; No ?- element( 5, LL ). LL = [5|_G208] ; LL = [_G207, 5|_G211] ; LL = [_G207, _G210, 5|_G214] Yes The last query has infinitely many answers. We could go on forever.

47 CSI 2115, Prolog, page 47 Non-determinism (4) Here is an immortal classic of Prolog teaching: % list L2 appended to [] is L2 append( [], L2, L2 ). % list L2 appended to [E | L1] has % E as its head, % L2 appended to L1 as its tail. append( [E | L1], L2, [E | L3] ) :- append( L1, L2, L3 ). This predicate has an astounding variety of uses! First of all, simple concatenation of lists: ?- append( [a], [b], LL ). LL = [a, b] ; No

48 CSI 2115, Prolog, page 48 Non-determinism (5) Next, find the second list: ?- append( [a], X, [a, b, c] ). X = [b, c] ; No Or the first list: ?- append( Y, [c], [a, b, c] ). Y = [a, b] ; No

49 CSI 2115, Prolog, page 49 Non-determinism (6) We can even find both lists! ?- append(F, S, [a, b]). F = [] S = [a, b] ; F = [a] S = [b] ; F = [a, b] S = [] ; No Or there can be no information about any lists... ?- append( F, S, FS ). F = [] S = _G158 FS = _G158 ; F = [_G239] S = _G158 FS = [_G239|_G158] ; F = [_G239, _G245] S = _G158 FS = [_G239, _G245|_G158] Yes

50 CSI 2115, Prolog, page 50 Non-determinism (7) Finally, this mixed affair: ?- append([X, 55], [Y], [77, Z, 20]). X = 77 Y = 20 Z = 55 ; No It works because Prolog cleverly matches objects. [Y] appended to [X, 55] gives [X, 55, Y]. Now we put together: [X, 55, Y] [77, Z, 20]

51 CSI 2115, Prolog, page 51 Non-determinism (8) On the other hand, in this query ?- append([X, 55], [Y], [77, Z]). we have [X, 55, Y] against [77, Z] — a match fails because the lists have different lengths! Other examples of mismatches for lists: [a, b, c] and [b | Y] different heads [1, 2, 3, 4] and [1, 3 | T] different tails, or recursively different heads in [2, 3, 4] and [3 | T]

52 CSI 2115, Prolog, page 52 Non-determinism (9) Finally, a most beautiful definition: intersect( List1, List2 ) :- element( X, List1 ), element( X, List2 ). ?- intersect( [a, c, e, g], [b, c, d] ). Yes ?- intersect( [a, c, e, g], [b, d, f] ). No Two lists intersect if they have a common element.

53 CSI 2115, Prolog, page 53 A bit of terminology Facts and rules together are called clauses. A group of clauses with the same name and the same number of parameters makes up a predicate. Some predicates that we saw in these notes: alcoholicman avoidno_hat_at_all catch_coldsno_hat_in_winter divisor_setnon_drinker drinksprime illsmokes in_rangewill_dance in_range2will_talk

54 CSI 2115, Prolog, page 54 A bit of terminology (2) Objects in Prolog are called terms. A term can be: a constant, a number, a variable, a compound object (in particular a list). Terms are the only data structures in Prolog — and they are quite sufficient!

55 CSI 2115, Prolog, page 55 A note on semantics There are no automatic checks in Prolog to ensure the semantic integrity of your program. For example: healthy_habits( X ) :- drinks( X, _Y ), smokes( X ). Formally, this is correct, but the real-world relationship that this name suggests does not hold! This is even worse: likes( jim, mary ) :- \+ likes( jim, mary ). Prolog accepts it as a syntactically correct rule, but cannot use it properly: there is an infinite loop. ?- likes( jim, mary ). ERROR: (user://1:25): Out of local stack continued...

56 CSI 2115, Prolog, page 56 A note on semantics (2) If you write tall( millie ). short( millie ). both these (conflicting!) facts will be recorded. tall and short are symbols without any special meaning. Prolog does not know that there is a connection: the programmer must specify it. Finally, if you give the same fact twice, it will be recorded twice. beer( grolsch ). beer( grolsch ). ?- beer( B ). B = grolsch ; No... concluded

57 CSI 2115, Prolog, page 57 Last words Prolog has much more to offer. You are ready to explore it on your own: Advanced control, including the cut. Customizable term syntax. Logic grammars. Dynamic (on-the-fly) modification of Prolog code. Programming with trees and graphs. Debugging tools. Programming in the large (modules). Graphics and user interface programming. Here are some applications where Prolog is a programming language of choice, for the best of software engineering reasons. Rapid software prototyping. Deductive databases. Language design and development. Constraint programming. Artificial Intelligence: Games, Planning, Machine Learning, Natural Language Processing.


Download ppt "CSI 2115, Prolog, page 1 Logic programming in Prolog A little background Prolog warm-up SWI Prolog A session with Prolog Two interpretations A bit of terminology."

Similar presentations


Ads by Google