Dave Reed

1 / 20

# Dave Reed - PowerPoint PPT Presentation

Dave Reed. 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. Test vs. find. Prolog programs define relations:

I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.

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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.

- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript

Dave Reed

• 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

Test vs. find
• Prolog programs define relations:
• query w/ constants: "test" whether relation holds between the constants
• query w/ variables: "find" values for which the relation holds

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

X = a ;

X = b ;

X = c ;

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]

Yes

with a variable as first argument, the query is used to "find" members of the given list

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

Append predicate
• another useful predefined predicate for list manipulation
• append(L1,L2,L3): L3 is the result of
• placing the items in L1 at the front of L2
• can be used in reverse to partition a list

?- append([a,b], [c,d], L).

L = [a,b,c,d]

Yes

?- 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

• again, we could define append ourselves:

append([], L, L).

append([H|T], L, [H|A]) :-

append(T, L, A).

as we saw with ancestor example,

clause ordering is important with

recursive definitions

• if put rule first, infinite loop possible
Other list predicates

?- 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] ;

No

is_list(Term): succeeds if Term is a list

length(List,Len): Len is the number of items in List

nth0(Index,List,Item): Item is the item at index Index of List(starting at 0)

nth1(Index,List,Item): Item is the item at index Index of List(starting at 1)

reverse(List,RevList): RevList is List with the items in reverse order

delete(List,Item,NewList): NewList is the result of deleting every occurrence of Item from List

select(Item,List,Remain): Remain is the List with an occurrence of Item removed

not predicate

?- 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.

No

• 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
• anything Prolog can't prove true it assumes to be false!
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 backwards & forwards
• palindrome([]).
• palindrome(List) :- reverse(List, Rev), List = Rev.

suppose we want to define relation to see if a list has duplicates

has_dupes(List): succeeds if List has at least one duplicate element

• has_dupes([H|T]) :- member(H, T).
• has_dupes([_|T]) :- has_dupes(T).

suppose we want the opposite relation, that a list has no dupes

no_dupes(List): succeeds if List has no duplicate elements

• no_dupes(List) :- not( has_dupes(List) ).
Built-in comparison operators
• X = Ydoes more than test equality, it matches X with Y, instantiating variables if necessary
• X \= Ydetermines 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
• Note: arithmetic operators (+, -, *, /) are not evaluated

4 + 2  +(4, 2)

• can force evaluation using 'is'

?- X = 4 + 2. ?- X is 4 + 2.

X = 4+2 X = 6

Yes Yes

?- foo = foo.

Yes

?- X = foo.

X = foo

Yes

?- [H|T] = [a,b,c].

H = a

T = [b,c]

Yes

?- foo \= bar.

Yes

?- X \= foo.

No

?- 4+2 = 6.

No

Arithmetic operations
• arithmetic comparisons automatically evaluate expressions

X =:= Y X and Y must both be arithmetic expressions (no variables)

X =\= Y

X > Y ?- 12 =:= 6+6.

X >= Y Yes

X < Y

X =< Y ?- X =:= 6+6.

ERROR: Arguments are not sufficiently instantiated

• Example:
• sum_of_list(ListOfNums, Sum): Sum is the sum of numbers in ListOfNums

sum_of_list([], 0).

sum_of_list([H|T], Sum) :-

sum_of_list(T,TailSum), Sum is H + TailSum.

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

• num_occur(_,[],0).
• num_occur(H, [H|T], N) :-
• num_occur(H, T, TailN), N is TailN+1.
• num_occur(H, [_|T], N) :-
• num_occur(H, T, TailN), N is TailN.

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: +(2, 3) 2 + 3

user defined? likes(dave, cubs)  dave likes cubs

• operators have the following characteristics
• position of appearance

prefix e.g., -3

infix e.g., 2 + 3

postfix e.g., 5!

• 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 is a constant

Prec is an integer in range 0 – 1200 (lower number binds tighter)

PosAssoc is a constant of the form

xf, yf (postfix)

fx, fy (prefix)

xfx, xfy, yfx, yfy (infix)

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

• Example: :- op(300, xfx, likes).
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).

X = cubs

Yes

?- likes(Who, What).

Who = dave

What = cubs ;

Who = kelly

What = and(java, and(scheme,prolog)) ;

No

?- dave likes X.

X = cubs

Yes

?- Who likes What.

Who = dave

What = cubs ;

Who = kelly

What = java and scheme and prolog ;

No

by defining functors/predicates as operators, can make code more English-like

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
• Note: always define ops at top of the program (before use)
IQ Testchoose the most likely answer by analogy

Question 1:

Question 3:

Question 2:

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) OR small sized triangle
• sized(large, square)OR large sized square
• functors: inside, above
• inside(small sized circle, large sized square).
• above(large sized triangle, small sized square).
• need to represent questions as well
• operators:is_to, as (bind looser than sized, so higher prec #)
• predicate:question
• question(Name, F1 is_to F2 as F3 is_to [A1,A2,A3]).
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

• look up the question based on its name
• find a transformation that takes F1 to F2
• apply that rule to F3 to obtain a potential solution
• test to see if that solution is among the answers to choose from

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%%% 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).

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),

%%% questions (as before)

%%% transformations (as before)

Analogy reasoner

Answer = inside(small sized square, large sized circle) ;

Answer = inside(small sized square, large sized circle) ;

No

Answer = above(large sized triangle, small sized triangle) ;

Answer = above(large sized triangle, small sized triangle) ;

No

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:

• it is possible for 2 different transformations to produce different answers
• must either
• refine the transformations (difficult)
• use heuristics to pick most likely answer (approach taken by Green)