1 / 43

More Built-in Predicates

More Built-in Predicates. Notes for Ch.7 of Bratko For C ENG421&553 Fall 03. Testing the Type of Terms. data objects (terms). var( X) succeeds if X is an uninstantiated variable nonvar( X) atom( X) succeeds if X currently stands for an atom integer( X) float( X)

danyl
Download Presentation

More Built-in Predicates

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. More Built-in Predicates Notes for Ch.7 of Bratko For CENG421&553Fall03

  2. Testing the Type of Terms data objects (terms) • var( X) succeeds if X is an uninstantiated variable • nonvar( X) • atom( X) succeeds if X currently stands for an atom • integer( X) • float( X) • number( X) number (integer or float) • atomic( X) number or atom • compound( X) structure • See examples of the book Compound objects (structures) simple objects constants variables atoms numbers

  3. Testing the type of terms • Prolog has many built-in features, depending on the implementation. Some of the mostly used: • Testing of the type. Useful to avoid error messages for not or wrongly instantiated variables: ..., integer(X), integer(Y), Z is X + Y, ...

  4. /* count1(Atom,List,Number) if Number is the number of terms in List that unify with Atom */ count1( _,[],0). count1( A,[ A|T],N) :- !, count1( A,T,N1), N is N1+1. count1( A,[ _|L],N) :- count1( A,L,N). /* count2(Atom,List,Number) if Number is the number of atoms in List that are identical to Atom */ count2( _,[],0). count2(A,[ B|T],N) :- atom( B), A = B, !, % B is atom A? count2( A,T,N1), N is N1+1 ; count2( A,T,N). Example

  5. Example: Counting Atoms • ch7_1.pl • We want to count actual occurrences of an atom, not terms that match an atom • count1(Atom,List,Number) counts terms that match Atom 3 ?- count1(a,[a,b,X,Y],Na). X = a Y = a Na = 3 • count2(Atom,List,Number) counts actual occurrences of Atom 5 ?- count2(a,[a,b,X,Y],Na). X = _G304 Y = _G307 Na = 1

  6. Cryptarithmetic Puzzle • SEND + MORE = MONEY • Assign distinct decimal digits to distinct letters so that the sum is valid • Albert Newell and Herbert Simon studied in depth puzzle like these in their study of human problem solving (Human Problem Solving, Prentice Hall, 1972) • People use a mixture of trial and error and constraint processing: e.g., M must be 1, S must be 8 or 9, O must be 0, etc.

  7. Cryptarithmetic Puzzle II • sum( N1,N2,N) if N is N1+N2 • Numbers are represented by lists of digits: the query is: • ?-sum( [S,E,N,D],[M,O,R,E],[M,O,N,E,Y]). • We need to define the sum relation; we generalize to a relation sum1, with • Carry digit from the right (before summing, C1) • Carry digit to the left (after summing, C) • Set of digits available before summing (Digits1) • Set of digits left after summing (Digits) • sum1( N1,N2,N,C1,C,Digits1,Digits)

  8. Cryptarithmetic Puzzle III • Example: 1 ?- sum1([H,E],[6,E],[U,S],1,1,[1,3,4,7,8,9],Digits). H = 8 E = 1 U = 4 S = 3 Digits = [7, 9] • There are several (four, in fact) other answers. 1<- <-1 8 1 6 1 4 3

  9. Cryptarithmetic Puzzle IV • We start off with all digits available, we do not want any carries at the end, and we do not care about which digits are left unused: • sum(N1,N2,N) :- sum1(N1,N2,N,0,0,[0,1,2,3,4,5,6,7,8,9],_). • We assume all three lists are of the same lengths, padding with zeros if necessary: • ?- sum([0,S,E,N,D],[0,M,O,R,E],[M,O,N,E,Y]).

  10. Cryptarithmetic Puzzle V sum1( [], [], [], C, C, Digits, Digits). sum1( [D1|N1], [D2|N2], [D|N], C1, C, Digs1, Digs) :- sum1( N1, N2, N, C1, C2, Digs1, Digs2), digitsum( D1, D2, C2, D, C, Digs2, Digs). digitsum( D1, D2, C1, D, C, Digs1, Digs) :- del_var( D1, Digs1, Digs2), % Select an available digit for D1 del_var( D2, Digs2, Digs3), % Select an available digit for D2 del_var( D, Digs3, Digs), % Select an available digit for D S is D1 + D2 + C1, D is S mod 10, % Reminder C is S // 10. % Integer division

  11. Cryptarithmetic Puzzle VI • Nonderministic deletion of variables del_var( A, L, L) :- nonvar(A), !. % A already instantiated del_var( A, [A|L], L). del_var( A, [B|L], [B|L1]) :- del_var(A, L, L1).

  12. Constructing and Decomposing Terms • Clauses are terms too! • As in LISP, data and programs have a common representation: S-expressions (atoms or lists) in LISP, terms in Prolog 2 ?- consult(user). |: a. |: a :- b. |:quit. 3 ?- clause(a,X). X = true ; X = b ; No

  13. Clauses are Terms • The principal functor of a clause is its neck (:- ) 4 ?- consult(user). |: :-(b,c). |: quit. % user compiled 0.00 sec, 32 bytes Yes 5 ?- listing(b). b :- c. Yes

  14. Constructing and decomposing terms • Built-in predicates for constructing and decomposing terms: functor, arg, and ‘=..’. First ‘=..’, an infix operator, and read as ‘univ’: Term =.. L is true if L is a list containing the principal functor of Term, followed by its arguments. Examples: ?- f(a,b) =.. L. L = [f, a, b] ?- T =.. [rectangle,3,5]. T = rectangle(3, 5) ?- Z =.. [p, X, f(X,Y)]. Z = p(H2, f(H2, H4)) X = H2 Y = H4

  15. Constructing and decomposing terms • Necessity of ‘=..’, suppose we want to manipulate geometric figures. Let us represent them as square(Side) triangle(Side1, Side2, Side3) circle(R) Operation to enlarge figures: enlarge(Fig1, Factor, Fig2) with Fig1 and Fig2 having the same functor and the arguments of Fig2 are those of Fig1 multiplied by Factor. Suppose that all variables are already instantiated. Then we can define enlarge as:

  16. Constructing and decomposing terms enlarge(square(S), F, square(S1)) :- S1 is F * S. enlarge(circle(R), F, circle(R1)) :- R1 is F * R. enlarge(rectangle(A,B), F, rectangle(A1,B1)) :- A1 is F * A, B1 is F * B. This works but is awkward if we have many figure types. And in fact all definitions are similar! Other attempt: enlarge(Type(Par), F, Type(Par1)) :- Par1 is F * Par. This is not allowed in Prolog, since the functor should be an atom. Moreover, we still have to define enlarge for figure types with more arguments.

  17. Constructing and decomposing terms • Solution: use ‘=..’ enlarge(Fig, F, Fig1) :- Fig =.. [Type | Pars], multiplylist( Pars, F, Pars1), Fig1 =.. [Type | Pars1]. multiplylist([], _, []). multiplylist([X|L], F, [X1|L1]) :- X1 is F * X, multiplylist(L, F, L1). Testing: ?- enlarge(ellipse(5,7), 2.5, X). X = ellipse(12.5, 17.5)

  18. Constructing and decomposing terms • To extract the functor and its arity of a structure, we can use ‘=..’, but better is functor(Term, F, N) and to extract the Nth argument of a structure, use arg(N, Term, A) Examples to illustrate: ?- functor(triangle(1,2,3), Fun, Arity). Fun = triangle Arity = 3 ?- Date = date(december, 6, 2005), arg(1, Date, Month), arg(2, Date, Day), arg(3, Date, Year). Date = date(december, 6, 2005) Month = december Day = 6 Year = 2005

  19. univ • Term =.. L, if • L is a list containing the principal functor of Term, followed by Term’s argument • Examples on page 170-171 • try_call :- % Here, Goal is a term Goal =.. [ member| [a, [a,b,c]]], Goal. % Here, Goal is a predicate • Example: • substitute( Subterm,Term,Subterm1,Term1) • ?-substitute( sin(x),2*sin(x)*f(sin(x)),t,F).

  20. % Figure 7.3 A procedure for substituting a subterm of a term by another subterm. % substitute( Subterm, Term, Subterm1, Term1): % if all occurrences of Subterm in Term are substituted % with Subterm1 then we get Term1. % Case 1: Substitute whole term substitute( Term, Term, Term1, Term1) :- !. % Case 2: Nothing to substitute substitute( _, Term, _, Term) :- atomic(Term), !. % Case 3: Do substitution on arguments substitute( Sub, Term, Sub1, Term1) :- Term =.. [F|Args], % Get arguments substlist( Sub, Args, Sub1, Args1), % Perform substitution on them Term1 =.. [F|Args1]. substlist( _, [], _, []). substlist( Sub, [Term|Terms], Sub1, [Term1|Terms1]) :- substitute( Sub, Term, Sub1, Term1), substlist( Sub, Terms, Sub1, Terms1).

  21. univ • Example: • fig7_3.pl • substitute( Subterm,Term,Subterm1,Term1) • ?-substitute( sin(x),2*sin(x)*f(sin(x)),t,F). • An occurrence of Subterm in Term is something in Term that matches Subterm • If Subterm = Term, then Term1 = Subterm1 Else if Term is atomic, then Term1 = Term Else carry out the substitution on the arguments of Term

  22. Dynamic Goals • Goals may be created at run time, as in: Obtain( Functor), Compute( Arglist), Goal =.. [ Functor|Arglist], Goal. % works in AMZI; with some Prologs, call( Goal) • try_call :- Goal =.. [ member| [a, [a,b,c]]], % Goal is a term Goal. % Goal is a predicate • This is also an example of Prolog’s ambiguous syntax: the first Goal is a term (a variable), while the second Goal is a predicate • Examples on page 173-174

  23. Equality and Comparison • X = Y matching (unification) • X is E matches arithmetic value • E1 =:= E2 arithmetic • E1 =\= E2 arithmetic inequality • T1 == T2 literal equality of terms(same structure and all correponding components are the same) • T1 \== T2 not identical • T1 @< T2 term comparison

  24. Various kinds of equality and comparison • Prolog has various interpretations of equality and hence different predicates to test equality. Already seen: X = Y which is true if X and Y match. Further X is E which is true if X matches the value of expression E. Also: E1 =:= E2 which is true if the values of the expressions E1 and E2 are equal. In contrast we use E1 =\= E2 when the values of the expressions E1 and E2 are not equal.

  25. Various kinds of equality and comparison • Another kind of equality is literal equality, written as T1 == T2 which is true if terms T1 and T2 are identical, i.e., exactly the same structure and all components are equal. The complementary relation: T1 \== T2 when the terms T1 and T2 are not identical. Some examples: ?- f(a,b) == f(a,b). yes ?- f(a,b) == f(a,X). no ?- f(a,X) == f(a,Y). no

  26. Various kinds of equality and comparison • Example: counting the number of literal occurrences of a term in a list: count(_, [], 0). count(Term, [Head | L], N) :- Term == Head, !, count(Term, L, N1), N is N1 + 1 ; count(Term, L, N).

  27. Various kinds of equality and comparison • Besides an arithmetic ordering relation (<, =<. >, >=) Prolog also knows the alphabetical ordering, with built-in predicates @<, @=<, @>, @>=. I.e., ?- paul @< peter. yes The precedence for structures is determined first by their functor, and then by the components, from left to right: ?- f(2) @< f(3). yes ?- f(a, g(b), c) @< f(a, h(a), a). yes

  28. Database manipulation • A Prolog knowledge base is in fact a kind of database, with facts and rules. Besides consult/reconsult Prolog has several other predicates to manipulate it. Some of the most important ones: assert(C) adds clause C to the knowledge base. Depending on implementation, this will be at the front or at the back. For explicit control, use asserta (at the front) or assertz (at the back). To delete a clause, use retract(C) This deletes the first clause from the knowledge base matching C. To delete all clauses matching C at once, use retractall(C)

  29. Database manipulation • To show the contents of the knowledge base at the moment use listing. Alternatively, use listing(Pred) to show only the clauses for predicate Pred, irrespective of arity, or use listing(Pred/N) for a listing of the clauses for predicate Pred with arity N. • Suppose we start a new Prolog session. The following user-Prolog conversation is illustrative: ?- listing. yes% the knowledge base is still empty ?- assert(getal(1)), listing. user:getal(1).% the first fact yes

  30. Database manipulation ?- assert(getal(2)), assert(getal(3)), listing. user:getal(1).% new facts are added user:getal(2).% in Amzi! Prolog by default user:getal(3).% at the end Yes ?- asserta(getal(4)),assertz(getal(5)),listing. user:getal(4).% explicitly add a fact user:getal(1).% at the front user:getal(2). user:getal(3). user:getal(5).% or at the end yes

  31. Database manipulation ?- retract(getal(2)), listing. user:getal(4). user:getal(1).% delete the clause getal (2) user:getal(3). user:getal(5). yes ?- retract(getal(_)), listing. user:getal(1). user:getal(3).% delete one clause for getal user:getal(5).% (the first one) yes ?- retractall(getal(_)), listing. yes% delete all clauses for getal

  32. Database manipulation • To add a rule, use the following syntax: ?- assert( (nice(X) :- not ugly(X)) ). • Useful application of asserta: to store already computed answers. E.g., suppose we have a predicate solve(Problem, Solution) Then we can ask for a solution and store it, by ?- solve(problem1, Solution), asserta(solve(problem1, Solution)). The first time we call solve(problem1, Solution) it is stored at the front of the knowledge base (it is “memorized”). A second time this stored solution is used (and probably much quicker).

  33. Database manipulation • As an application: let us make and store a multiplication table for all pairs of numbers X and Y from 0 to 9. Using the fail goal we force backtracking, doing a next pair. maketable :- L = [0,1,2,3,4,5,6,7,8,9], member(X,L), member(Y,L), Z is X * Y, assert(product(X,Y,Z)), fail. The question: ?- maketable. will of course fail, but as a side effect produce the desired table.

  34. Database manipulation • E.g. ?- listing(product). user:product(0, 0, 0). user:product(0, 1, 0). user:product(0, 2, 0). ... user:product(9, 9, 81). ?- product(M,N,8). M = 1 N = 8 ; M = 2 N = 4 ; M = 4 N = 2 ; M = 8 N = 1 ; no

  35. Prolog Database Manipulation • asserta/1 • assertz/1 • Same as assert/1 • retract/1 • Only dynamic predicates may be asserted, retracted, etc. • dynamic +Functor/+Arity, . . . • See ..\amzi_6-2-14\docs\pro\prfrtop.htm • See examples on page 177-180.

  36. Control Facilities • once( P) • The predicate once/1 behaves like call/1 except it is only executed once. This is useful for isolating code that you don't intend to be backtracked into, and makes for more readable code than inserting lots of cuts (!). • We already encountered: • !; the cut, always succeeds • fail; always fails • true; always succeeds • not(P) or not P; succeeds if P fails and vice versa(alternative syntax: \+ P) Two new goals: • call(P); succeeds if P succeeds • repeat; always succeeds, but is non-deterministic. So every time it is reached by backtracking it generates a new execution branch. It is as defined by repeat. repeat :- repeat.

  37. Control facilities • Application of repeat: dosquares :- repeat, write('Input please: '), read(X), (X = stop, ! ; Y is X*X, write('The square of '), write(X), write(' is: '), write(Y), nl, fail ).

  38. bagof, setof, and findall • bagof( X,P,L) if L is the list of Xs such that P(X) holds • setof( X,P,L) is like bagof, but without duplication and the list is ordered • Numbers ordered by < • Others alphabetically ordered • Functors,parameters... Compared respectively • Read ^ as “there exists” in bagof and setof • findall( X,P,L) is like bagof but collects all objects X regardless of (possibly) different solutions for variables in P that are not shared with X • Code for findall is in fig7_4.pl • renamed findall1, because findall is built-in

  39. bagof, etc. Examples • age( peter,7). age( ann,5). age( pat,8). age( tom,5). • ?- bagof( Child,age(Child,5),L). • L=[ann,tom] • ?- bagof( Child,age(Child,Age),L). • Age=7 L=[peter] • Age=5 L=[ann,tom] • Age=8 L=[pat] • ?- bagof( Child,Age^age(Child,Age),L). • L=[peter,ann,pat,tom] • ?- bagof( Age,Child^age(Child,Age),L). • L = [7, 5, 8, 5] • ?- setof( Age, Child^age(Child,Age),L). • L = [5, 7, 8] • ?- setof( Age:Child,age(Child,Age),L). • L = [5:ann, 5:tom, 7:peter, 8:pat] • ?-findall( Child,age( Child,Age),L). • L = [peter, ann, pat, tom]

  40. bagof, setof and findall • To generate a list of all solutions for a goal, use findall(X, P, L) This will produce a list L of all instantiations of X satisfying P. For instance likes(fred, juice). likes(tom, milk). likes(jane, juice). likes(jane, coke). ?- findall(X, likes(X,Y), L). L = [fred, tom, jane, jane] ?- findall(Y, likes(X,Y), L). L = [juice, milk, juice, coke]

  41. bagof, setof and findall • Bagof is similar, but instantiates “unqueried” variables: ?- bagof(X, likes(X, juice), L). L = [fred, jane] ?- bagof(X, likes(X,Y), L). Y = juice L = [fred, jane] ; Y = milk L = [tom] ; Y = coke L = [jane] ; no

  42. bagof, setof and findall • To state that we don’t care on the instantiation of an “unqueried” variable, use the infix operator ‘^’ between variable name and predicate: ?- bagof(X, Y^likes(X,Y), L). L = [fred, tom, jane, jane] • The predicate setof is just like bagof, with two exceptions: • Duplicate terms, if any, will be removed • The output list is alphabetically ordered ?- setof(X, Y^likes(X,Y), L). L = [fred, jane, tom] ?- setof(Y, X^likes(X,Y), L). L = [juice, coke, milk]

  43. % Figure 7.4 An implementation of the findall relation, findall1( X, Goal, Xlist) :- call( Goal), % Find a solution assertz( queue(X) ), % Assert it fail; % Try to find more solutions assertz( queue(bottom) ), % Mark end of solutions collect( Xlist). % Collect the solutions collect( L) :- retract( queue(X) ), !, % Retract next solution ( X == bottom, !, L = [] % End of solutions? ; L = [X | Rest], collect( Rest) ). % Otherwise collect the rest % age relation for examples age( peter,7). age( ann,5). age( pat,8). age( tom,5).

More Related