7
- 1 - CSNB234 Artificial Intelligence Prolog Programming LAB 3: Syntax and Semantics Contents 1. Simple data objects (atoms, numbers, variables) and Structured objects 2. Matching / Unification. 3. Declarative and Procedural meaning of a Program. 4. Lists – unification and searching. 1. Data Objects: Constants, Variables, Structures Data objects in Prolog can be classified as follows: Constants They name specific things or predicates. 2 types: o Atoms: (likes, a, =, --,'Stuf', married_man) o Numbers These are not atoms o 314a5 (cannot start with a number), o george-smith( cannot contain a hyphen) o George (cannot start with a capital letter) o _something (cannot start with underscore) Variables Written in uppercase or starting with uppercase or underscore _ Examples: X, Input, _something, _ (anonymous variable) Anonymous variables need not have consistent interpretations (they need not be bound to the same value): ?- likes(_, john). %does anybody like John? ?- likes(_, _). %does anybody like anybody?

CSNB234 Artificial Intelligence Prolog Programming

  • Upload
    others

  • View
    5

  • Download
    0

Embed Size (px)

Citation preview

- 1 -

CSNB234 Artificial Intelligence

Prolog Programming

LAB 3: Syntax and Semantics

Contents

1. Simple data objects (atoms, numbers, variables) and Structured objects

2. Matching / Unification.

3. Declarative and Procedural meaning of a Program.

4. Lists – unification and searching.

1. Data Objects: Constants, Variables, Structures

Data objects in Prolog can be classified as follows:

Constants • They name specific things or predicates.

• 2 types:

o Atoms: (likes, a, =, --,'Stuf', married_man)

o Numbers

• These are not atoms

o 314a5 (cannot start with a number),

o george-smith( cannot contain a hyphen)

o George (cannot start with a capital letter)

o _something (cannot start with underscore)

Variables • Written in uppercase or starting with uppercase or underscore _

• Examples: X, Input, _something, _ (anonymous variable)

• Anonymous variables need not have consistent interpretations (they need not be bound to the same value):

?- likes(_, john). %does anybody like John?

?- likes(_, _). %does anybody like anybody?

- 2 -

Structures • Used to organize the data.

• Structured objects (or simply structures) are objects that have several components. The components themselves can, in turn, be structures

• A structure is specified by its functor (name) and its components.

• All structured objects can be pictured as trees (see below). The root of the tree is the functor, and the offsprings of the root are the components.

• If a component is also a structure, then it is a subtree of the tree that corresponds to the whole structured object.

• Example 1.

Date (as a tree) Date (in prolog)

example:

1. owns(john, book(wuthering_heights, bronte)).

2. book(wuthering_heights, author(emily, bronte)).

?- owns(john, book(X, author(Y, bronte))).

%does John own a book (X) by Bronte (Y, bronte)?

2. Arithmetic Operators

Some of the predefined operators : + (addition), - (subtraction), * (multiplication), / (division), ** (power), // (integer division), mod (modulo, the remainder of integer division).

The following queries demonstrates the use of = and is :

Query Answer Comments ?- X = 1+2. X = 1+2 Why not X = 3?

The expression 1 + 2 denotes a Prolog term where + is the functor and 1 and 2 are its arguments.

There is nothing in the above goal to force Prolog to actually activate the addition operation.

?- X is 1+2.

X = 3

The addition was carried out by a special procedure that is associated with the operator is. We call such

procedures built-in procedures. ?- X is 5/2, Y is 5//2,

Z is 5 mod 2.

X= 2.5

Y = 2

Z = 1

Parentheses can be used to indicate different associations.

Evaluation is carried out from left to right without parentheses

Query Answer Comments ?- X is 5-2*2. X = 1 2*2 is evaluated, followed by 5-5

?- X is (5-2)*2 X = 6 5-2 is evaluated, followed by 3*2

- 3 -

Arithmetic is also involved when comparing numerical values.

Query Answer Comments ?- 277*3>10000. no * is evaluated followed by >

?- 277*38>10000. yes “

Suppose that we have in the program a relation born that relates the names of people with their birth years. Then we can retrieve the names of people born between 1980 and 1990 inclusive with the following question: ?- born(Name, Year),Year >= 1980, Year =< 1990.

where

Relations Meaning

X > Y X is greater than Y

X < Y X is less than Y

X >= Y X is greater than or equal to Y

X =< Y X is less than or equal to Y

X =:= Y X and Y are equal X

X\= Y X and Y are not equal

Examples:

Query Answer ?- 1+2 =:= 2+1. Yes

?- 1+2 = 2+1. No

?- 1+A = B+2. A A = 2, B = 1

3. Declarative and Procedural meaning of Prolog programs

Prolog programs can be understood in two ways:

declaratively procedurally.

Consider a clause

P:- Q,R. where P, Q and R have the syntax of terms.

Comparison between declarative and procedural

Declarative Procedural

P is true if Q and R are true. From Q and R follows P.

To solve problem P, first solve the subproblem Q and then the subproblem R.

To satisfy P, first satisfy Q and then R.

determines whether a given goal is true, and if so, for what values of variables it is true.

define the logical relations between the head of the clause and the goals in the body.

determine the order in which the goals are processed.

- 4 -

Uses the concept of instance of a clause. An instance of a clause C is the clause

C with each of its variables substituted by some term.

A variant of a clause C is such an instance of the clause C where each variable is substituted by another variable.

For example, consider the clause hasachild( X) :- parent( X, Y).

Two variants of this clause are: hasachild( A) :- parent( A, B). hasachild( Xl) :- parent( Xl, X2).

Example instances of this clause are: hasachild(peter):-parent(peter, Z). hasachild(barry) :- parent(barry,

small(caroline) ).

Specifies how Prolog answers questions. To answer a question means to try to satisfy

a list of goals. They can be satisfied if the variables that

occur in the goals can be instantiated in such a way that the goals logically follow from the program.

A procedure for executing a list of goals with respect to a given program.

To 'execute goals' means: try to satisfy them.

4. Matching/Unification

Two terms unify

if they are the same term or

if they contain variables that can be uniformly instantiated with terms in such a way that the

resulting terms are equal.

This means that:

mia and mia unify

42 and 42 unify

woman(mia) and woman(mia) unify

This also means that:

vincent and mia do not unify

woman(mia) and woman(jody) do not unify

?- mia = mia.

Yes

This tells us that two constants unify if and only if they are exactly the same object. As mia and mia are the same atom, unification succeeds.

?- 2 = 2.

Yes

?- mia = vincent.

no

2 is the same number as 2 , and as mia is not the same atom as vincent , Prolog responds yes to the first query and no to the second.

? - X = mia, X = vincent.

no

Prolog will respond no. This query involves two goals, X = mia and X = vincent .

Taken separately, Prolog would succeed at both of them, instantiating X to mia in the first case and

to vincent in the second.

- 5 -

A n d that’s exactly the problem here: once Prolog has worked through the first goal, X is

instantiated to (and therefore equal to) mia , so that it simply can’t unify with vincent anymore.

H e n c e the second goal fails. An instantiated variable isn’t really a variable anymore: it has become

what it was instantiated with.

5. Lists

Lists is one of the simplest and most useful structures in Prolog, widely used in non-numeric programming.

A list is a sequence of any number of items, such as ann, tennis, tom, skiing. Such a list can be written in Prolog as:

[ ann, tennis, tom, skiing]

List are also trees and can can be empty [].

First item if list is the head. The rests form the tail. Example: [ann] is the head and [tennis, tom, skiing] is the tail. The head can be anything but the tail has to be a list.

Examples:

1. [ a, b, c, d] is a list

2. [Head | Tail ] where Head is a and Tail is a list [b, c, d]

3. Hobbies1 = [ tennis, music]

Hobbies2 = [ skiing, food]

L = [ann, [tennis, music], tom, [skiing, food]]

4. L = [a, b, c]

Tail = [b, c]

L = [a, Tail]

Operations on list

Check if an object is an element of a list

member[X, L] where X is an object and L is a list eg: member( b, [a,b,c])

sublist( [c,d], [a,b,c,d,e,f ]) checks if a list is part of another list. Gives true or false. Join 2 lists

conc[L1, L2, L3] where L1 and L2 are joint to be L3. Eg: conc([a, b], [c, d], R ) Add or delete an object to a list

add( X, L, [X | L] ) , del( X, L, Ll) Permutation

?- permutation( [a,b,c], P). permute [a, b, c] and put in P.

Example usage of list.

Lets say we have a list

[sofa, tv, radio, table, chair, bed, mirror].

We can represent the locations of things. Rather than having separate location predicates for each thing, we can have one location predicate

per container, with a list of things in the container.

list_where([sofa, tv], livingroom). list_where([table,chair],

kitchen).

list_where([bed, mirror], bedroom).

list_where([radio], everywhere).

We can ask questions about lists to Prolog:

?- [_,_,X] = [lesson, work, sleeping].

X = sleeping

?- list_where(X, everywhere).

X = [radio]

?- list_where(X, livingroom).

X = [sofa, tv]

- 6 -

6. List Unification [a,b,c] unifies with [Head|Tail] resulting in Head=a and Tail=[b,c]

?- [a,b,c] = [Head|Tail].

Head = a

Tail = [b, c]

[a] unifies with [H|T] resulting in H=a and T=[]

?- [a] = [H|T].

H = a

T = '[]'

[a,b,c] unifies with [a|T] resulting in T=[b,c]

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

T = [b, c]

[a,b,c] doesn't unify with [b|T]

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

no

[] doesn't unify with [H|T]

?- [] = [H|T].

no

[] unifies with []. Two empty lists always match

?- [] = [].

yes

Let’s consider the following fact. p([H|T], H, T). Let’s see what happens when we ask some simple queries.

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

X = a

Y = [b, c]

?- p([a], X, Y).

X = a

Y = '[]'

?- p([], X, Y).

no

7. List Searching

We can use lists within facts and rules.

One common way of using lists is to store information within a list and then subsequently search for this information when we run our programs.

In order to search a list, Prolog inspects the first item in a list and then goes on to repeat the same process on the rest of the list.

- 7 -

This is done by using recursion.

The search can either stop when we find a particular item at the start of the list or when we have searched the whole list, in which case the list to be searched will be the empty list

In order to do this, we have to be able to selectively pull the list apart.

How to take the head and a tail of a list: [Head|Tail]

This method constitutes the basis of the searching method. We shall use it to pull apart a list, looking at the first item each time, recursively looking at the tail, until we reach the empty list [], when we will stop.

Example:

Consider the following problem. How can I see if a particular item is on a particular list?

For example I want to test to see if item apples is on the list

[pears, tomatoes, apples, grapes].

One possible method of doing this is by going through the list, an item at a time, to see if we can find the item we are looking for.

The way we do this in Prolog is to say that we could definitely prove an item was on a list if we knew that the target item was the first one on the list. ie.

on(Item,[Item|Rest]). /* is the target item the head of the list */

Otherwise we could prove something was on a list if we could prove that although it didn't

match the existing head of the list, it nonetheless would match another head of the list if we disregarded the first item and just considered the rest of the list i.e.

on(Item,[DisregardHead|Tail]):-

on(Item,Tail).

We now have a program consisting of a fact a nd a rule for testing if something is on a rule. To recap, it sees if something is the first item in the list. If it is we succeed. If it is not, then we throw away the first item in the list and look at the rest.

on(Item,[Item|Rest]). % base case, if the list is nil

on(Item,[DisregardHead|Tail]):-

on(Item,Tail). % recursive call

Suppose we pose the query:

?- on(apples, [pears, tomatoes, apples, grapes]).

yes

The first clause of on requires the first argument of on to match with the list head. However apples and pears do not match. Thus we must move on to the second clause. This splits the list up as follows:

DisregardHead = pears

Tail = [tomatoes,apples,grapes]

This now gives us the following goal in the body of our rule:

on(apples, [tomatoes, apples, grapes]).

Again, we see if apples and tomatoes match using our initial facts. Since they don't, we again use our second

clause to strip off the current list head, giving us the new goal.

on(apples,[apples, grapes]).

Since apples matches apples, our first clause succeeds as does our query.