Escolar Documentos
Profissional Documentos
Cultura Documentos
more Prolog
test vs. find built-in predicates
list operations: member, append, nth0, reverse, not, default vs. logical negation comparison operators, arithmetic
user-defined operators
position, precedence, associativity
query w/ constants: "test" whether relation holds between the constants query w/ variables: "find" values for which the relation holds with a variable as first argument, the query is used to "find" members of the given list
No
?- member(a, X). X = [a|_G260] ; X = [_G259,a|_G262] Yes ?- member(X, Y). X = _G209 Y = [_G209|_G270] ; X = _G209 Y = [_G275,_G209|_G278]
with a variable as the second argument, the query is used to "find" lists that have the given item as member
with both variables, the query is used to "find" general schemas for list membership
Yes
Append predicate
another useful predefined predicate for list manipulation
?- append([a,b], [c,d], L).
L = [a,b,c,d]
Yes
placing the items in L1 at the front of L2 can be used in reverse to partition a list again, we could define append ourselves:
append([], L, L). append([H|T], L, [H|A]) :append(T, L, A).
?- append(L1, L2, [a,b,c,d]). L1 = [] L2 = [a,b,c,d] ; L1 = [a] L2 = [b,c,d] ; L1 = [a,b] L2 = [c,d] ; L1 = [a,b,c] L2 = [d] ; L1 = [a,b,c,d] L2 = [] ; No
as we saw with ancestor example, clause ordering is important with recursive definitions
if put rule first, infinite loop possible
?- L = [a,b,c,d], length(L, Len), nth1(Len, L, X). L = [a,b,c,d] Len = 4 X = d Yes ?- reverse([a,b,a,c], Rev), delete(Rev, a, Del). Rev = [c,a,b,a] Del = [c,b] Yes ?- select(a, [a,b,a,c], R). R = [b,a,c] ; R = [a,b,c] ; No ?- select(a, L, [b,c]). L = [a,b,c] ; L = [b,a,c] ; L = [b,c,a] ;
removed
No
?- is_list([]). Yes ?- not(is_list([])). No ?- member(d, [a,b,c]). No ?- not(member(d, [a,b,c])). Yes ?- member(X, [a,b,c]). X = a Yes ?- not(member(X, [a,b,c])). No ?- X = d, not(member(X, [a,b,c])). X = d Yes ?- not(member(X, [a,b,c])), X = d.
not predicate
not defines the (default) negation
of conditional statements
when applied to relations with no variables, it is equivalent to logical negation () in reality, it returns the opposite of whatever its argument would return if X would succeed as a query, then not(X) fails if X would fail as a query, then not(X) succeeds
No
Programming exercises
suppose we want to define a relation to test if a list is palindromic
palindrome(List): succeeds if List is a list whose elements are the same
X = Y
does more than test equality, it matches X with Y, instantiating variables if necessary determines whether X & Y are not unifiable
for ground terms, this means inequality can think of as: not(X = Y) again, doesn't make a lot of sense for variables
X \= Y
Arithmetic operations
arithmetic comparisons automatically evaluate expressions
X X X X X X =:= Y =\= Y > Y >= Y < Y =< Y
Example:
sum_of_list(ListOfNums, Sum): Sum
Programming exercise
suppose we want to define relation to see how many times an item occurs in a list
num_occur(Item,List,N): Item occurs N times in List
is the first answer supplied by this relation correct? are subsequent answers obtained via backtracking correct?
User-defined operators
it is sometimes convenient to write functors/predicates as operators
predefined:
user defined?
+(2, 3)
likes(dave, cubs)
2 + 3
dave likes cubs
precedence
2 + 3 * 4 2 + (3 * 4)
associativity
8 5 - 2 8 (5 2)
op
new operators may be defined as follows
:- op(Prec, PosAssoc, Name). Name Prec
PosAssoc is a constant of the form xf, yf fx, fy xfx, xfy, yfx, yfy
the location of f denotes the operator position x means only operators of lower precedence may appear here y allows operators of lower or equal precedence
Operator example
%%% likes.pro likes(dave, cubs). likes(kelly, and(java, and(scheme,prolog))). %%% likes.pro :- op(300, xfx, likes). :- op(250, xfy, and). dave likes cubs. kelly likes java and scheme and prolog. ?- likes(dave, X). ?- dave likes X.
X = cubs
Yes ?- likes(Who, What). Who = dave What = cubs ; Who = kelly What = and(java, and(scheme,prolog)) ; No
X = cubs
Yes ?- Who likes What. Who = dave What = cubs ; Who = kelly What = java and scheme and prolog ; No
SWI-Prolog operators
the following standard operators are predefined in SWI-Prolog to define new operators
Name & Type are easy Precedence is tricky, must determine place in hierarchy
1200 1200 1150 1100 1050 1000 954 xfx -->, :fx :-, ?fx dynamic, multifile, module_transparent, discontiguous, volatile, initialization xfy ;, | xfy -> xfy , xfy \
900
900 700 600
fy \+
fx ~ xfx <, =, =.., =@=, =:=, =<, ==, =\=, >, >=, @<, @=<, @>, @>=, \=, \==, is xfy :
500
Question 1:
is to as is to
IQ Test
choose the most likely answer by analogy
Question 3:
is to as is to
A)
B)
C)
Question 2:
A) B) C)
is to
as
is to
A)
B)
C)
Analogy reasoner
want to write a Prolog program for reasoning by analogy (Evans, 1968)
need to decide on a representation of pictures constants: small, large, triangle, square, circle functor/operator: sized
sized(small, triangle) sized(large, square)
OR OR
IQ test questions
:- op(200, xfy, is_to). :- op(200, xfy, as). :- op(180, xfy, sized). question(q1, inside(small sized square, large sized triangle) is_to inside(small sized triangle, large sized square) as inside(small sized circle, large sized square) is_to [inside(small sized circle, large sized triangle), inside(small sized square, large sized circle), inside(small sized triangle, large sized square)]).
question(q2, inside(small sized circle, large sized square) is_to inside(small sized square, large sized circle) as above(small sized triangle, large sized triangle) is_to [above(small sized circle, large sized circle), inside(small sized triangle, large sized triangle), above(large sized triangle, small sized triangle)]).
question(q3, above(small sized square, large sized circle) is_to above(large sized square, small sized circle) as above(small sized circle, large sized triangle) is_to [above(large sized circle, small sized triangle), inside(small sized circle, large sized triangle), above(large sized triangle, small sized square)]).
Analogy transformations
also need to represent transformations predicate: transform
transform(Name, F1 is_to F2).
transform(invertPosition, inside(small sized Figure1, large sized Figure2) is_to inside(small sized Figure2, large sized Figure1)). transform(invertPosition, above(Size1 sized Figure1, Size2 sized Figure2) is_to above(Size2 sized Figure2, Size1 sized Figure1)). transform(invertSizes, inside(small sized Figure1, large sized Figure2) is_to inside(small sized Figure2, large sized Figure1)). transform(invertSizes, above(Size1 sized Figure1, Size2 sized Figure2) is_to above(Size2 sized Figure1, Size1 sized Figure2)).
Note: different but related transformations can have the same name
Analogy reasoner
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%% analogy.pro Dave Reed 1/23/02 %%% %%% A program based on Evans' analogy reasoner. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% :- op(200, xfy, is_to). :- op(200, xfy, as). :- op(180, xfy, sized).
to find an answer:
1. look up the question based on its name 2. find a transformation that takes F1 to F2 3. apply that rule to F3 to obtain a potential solution 4. test to see if that solution is among the answers to choose from
analogy(Question, Solution) :question(Question, F1 is_to F2 as F3 is_to Answers), transform(Rule, F1 is_to F2), transform(Rule, F3 is_to Solution), member(Solution, Answers).
Analogy reasoner
?- analogy(q1, Answer). Answer = inside(small sized square, large sized circle) ; Answer = inside(small sized square, large sized circle) ; No ?- analogy(q2, Answer). Answer = above(large sized triangle, small sized triangle) ; Answer = above(large sized triangle, small sized triangle) ;
No
?- analogy(q3, Answer). Answer = above(large sized circle, small sized triangle) ; No
Note: Questions 1 & 2 yield the same answer twice. WHY? Is it possible for a questions to have different answers?
Handling ambiguities
Question 4:
is to as is to
A)
B)
C)
?- analogy(q4, Answer).