0% found this document useful (0 votes)
168 views10 pages

Rules in Prolog: Abeera Afridi BS (SE) - 2018

The document discusses lists in Prolog. It notes that lists are enclosed in square brackets and elements are separated by commas. Lists can contain atoms, numbers, variables, and other lists as elements. The empty list contains no elements. Non-empty lists have a head, which is the first element, and a tail, which is the remaining list. The | operator is used to decompose lists into their head and tail, and is important for list manipulation in Prolog.

Uploaded by

Abeera Afridi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
168 views10 pages

Rules in Prolog: Abeera Afridi BS (SE) - 2018

The document discusses lists in Prolog. It notes that lists are enclosed in square brackets and elements are separated by commas. Lists can contain atoms, numbers, variables, and other lists as elements. The empty list contains no elements. Non-empty lists have a head, which is the first element, and a tail, which is the remaining list. The | operator is used to decompose lists into their head and tail, and is important for list manipulation in Prolog.

Uploaded by

Abeera Afridi
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 10

Abeera Afridi

BS(SE)-2018

Rules in prolog
A rule is a predicate expression that uses logical implication (:-) to describe a relationship
among facts. Thus a Prolog rule takes the form
left_hand_side :- right_hand_side .

This sentence is interpreted as: left_hand_side if right_hand_side. The left_hand_side is


restricted to a single, positive, literal, which means it must consist of a positive atomic
expression. It cannot be negated and it cannot contain logical connectives.

This notation is known as a Horn clause. In Horn clause logic, the left hand side of the clause is
the conclusion, and must be a single positive literal. The right hand side contains the premises.
The Horn clause calculus is equivalent to the first-order predicate calculus.

For example if someone, say a person B, is the parent of another person, person A, then person A
is the child of person B. Prolog allows us to capture this relationship as follows:

child( A, B ) :-

parent( B, A ).

This means that A is a child of B if B is the parent of A. The above rule has the following form:

Head :-

Body.

The Head is true if the Body is true. So if the facts in the Body are true then the head is true.
Note how close this is to conditionals in other languages. Up until this point we have only
developed facts. Facts are always true. Rules are only true if the body is true.

Examples of valid rules:

friends(X,Y) :- likes(X,Y),likes(Y,X). /* X and Y are friends if they like each other */


hates(X,Y) :- not(likes(X,Y)). /* X hates Y if X does not like Y. */
enemies(X,Y) :- not(likes(X,Y)),not(likes(Y,X)). /* X and Y are enemies if they don't like each
other */

Examples of invalid rules:

left_of(X,Y) :- right_of(Y,X) /* Missing a period */


likes(X,Y),likes(Y,X) :- friends(X,Y). /* LHS is not a single literal */
not(likes(X,Y)) :- hates(X,Y). /* LHS cannot be negated */
Abeera Afridi
BS(SE)-2018

Backtracking in Rules
We can also have backtracking in rules. For example consider the following program.
hold_party(X):-birthday(X),happy(X).
birthday(tom).

birthday(fred).

birthday(helen).

happy(mary).

happy(jane).

happy(helen).

If we now pose the query

?- hold_party(Who).

In order to solve the above, Prolog first attempts to find a clause of birthday, it being the first
subgoal of birthday. This binds X to tom. We then attempt the goal happy(tom). This will fail,
since it doesn't match the above database. As a result, Prolog backtracks. This means that Prolog
goes back to its last choice point and sees if there is an alternative solution. In this case, this
means going back and attempting to find another clause of birthday. This time we can use clause
two, binding X to fred. This then causes us to try the goal happy(fred). Again this will fail to
match our database. As a result, we backtrack again. This time we find clause three of birthday,
and bind X to helen, and attempt the goal happy(helen). This goal matches against clause 3 of
our happy database. As a result, hold_party will succeed with X=helen.
Abeera Afridi
BS(SE)-2018

Lab Exercise

OBJECT:Learning rules in prolog

1. Indicate whether the following are syntactically correct Rules.


 a :- b, c, d:- e f.

No.

 happy(X):- a , b.

Yes

 happy(X):- hasmoney(X) & has_friends(X).

No

 fun(fish):- blue(betty), bike(yamaha).

Yes

2. Consider the following program.


car(vw_beatle).
car(ford_escort).
bike(harley_davidson).
red(vw_beatle).
red(ford_escort).
blue(harley_davidson).

a) Write down a query if the following conditional statement is given


‘Something is fun if it is a red car or a blue bike’

fun(X) :-
red(X),
car(X).
fun(X) :-
blue(X),
bike(X).

b) How will prolog respond to the following query?


fun(What).

What=vw_beatle
Abeera Afridi
BS(SE)-2018

3. Write down the rules for the following conditional statements


a) M is the mother of X if she is a parent of X and is female

mother( M, X) :- parent( M, X, female( M).

b) F is the father of X if he is a parent of X and is male

father( F, X) :- parent( F, X),male( F).

4. Translate the following statements into prolog rules


a) Everybody who has a child is happy

happy(X) :- has_child(Y).

b) For all X, if X has a child who has a sister then X has two children.
X
hastwochildren(X):
-
parent(X, Y), Y Grandparent
sister(_, Y),
write(X), write(' has two children'), nl, false.
Z

5. Define the relation grandchild using the parent relation.

Solution:

grandchild(Z,X) :- parent(X,Y), parent(Y,Z).

6. Define the relation aunt(X,Y) in terms of the relation parent and sister.

aunt(X,Y):
-
sister(X, A),
parent(A, Y),
write(X), write(' is an aunt for '), write(Y), nl,
false.
Abeera Afridi
BS(SE)-2018

List In Prolog
List
List is just a plain old list of items. Slightly more precisely, it is a finite sequence of elements.
Here are some examples of lists in Prolog:
 [mia, vincent, jules, yolanda]
 [mia, robber(honey_bunny), X, 2, mia]
 []
 [mia, [vincent, jules], [butch, pet(butch)]]
 [[], dead(zed), [2, [b, chopper]], [], Z, [2, [b, chopper]]]

Some important things about these examples.


1. We can specify lists in Prolog by enclosing the elements of the list in square brackets
(that is, the symbols [ and ]). The elements are separated by commas. For example, our
first example [mia, vincent, jules, yolanda] is a list with four elements, namely mia,
vincent, jules, and yolanda. The length of a list is the number of elements it has, so our
first example is a list of length four.
2. From our second example, [mia,robber(honey_bunny),X,2,mia], we learn that all sorts of
Prolog objects can be elements of a list. The first element of this list is mia, an atom; the
second element is robber(honey_bunny), a complex term; the third element is X, a
variable; the fourth element is 2, a number. Moreover, we also learn that the same item
may occur more than once in the same list: for example, the fifth element of this list is
mia, which is same as the first element.
3. The third example shows that there is a very special list, the empty list. The empty list (as
its name suggests) is the list that contains no elements. What is the length of the empty
list? Zero, of course (for the length of a list is the number of members it contains, and the
empty list contains nothing).
4. The fourth example teaches us something extremely important: lists can contain other
lists as elements. For example, the second element of

[mia, [vincent, jules], [butch,pet(butch)]]

is the list [vincent,jules], and the third element is [butch,pet(butch)]]. In short, lists are
examples of recursive data structures: lists can be made out of lists. What is the length of
the fourth list? The answer is: three. The elements of the list are the things between the
outermost square brackets separated by commas. So this list contains three elements: the
first element is mia, the second element is [vincent, jules], and the third element is [butch,
pet(butch)].
7. The last example mixes all these ideas together. We have here a list which contains the
empty list (in fact, it contains it twice), the complex term dead(zed), two copies of the list
[2, [b, chopper]], and the variable Z. Note that the third (and the last) elements are lists
which themselves contain lists (namely [b, chopper]).
Abeera Afridi
BS(SE)-2018

Any non-empty list can be thought of as consisting of two parts: the head and the tail. The head
is simply the first item in the list; the tail is everything else. Or more precisely, the tail is the list
that remains when we take the first element away, i.e. the tail of a list is always a list again. For
example, the head of
[mia, vincent, jules, yolanda]

is mia and the tail is [vincent, jules, yolanda]. Similarly, the head of

[[], dead(zed), [2, [b, chopper]], [], Z, [2, [b, chopper]]]

is [], and the tail is [dead(zed), [2,[b,chopper]],[],Z,[2,[b, chopper]]]. And what are the head and
the tail of the list [dead(zed)]? Well, the head is the first element of the list, which is dead(zed),
and the tail is the list that remains if we take the head away, which, in this case, is the empty list
[].

Note that only non-empty lists have heads and tails. That is, the empty list contains no internal
structure. For Prolog, the empty list [] is a special, particularly simple, list.

Prolog has a special inbuilt operator | which can be used to decompose a list into its head and
tail. It is very important to get to know how to use |, for it is a key tool for writing Prolog list
manipulation programs.
The most obvious use of | is to extract information from lists. We do this by using | together with
matching. For example, to get hold of the head and tail of [mia,vincent, jules,yolanda] we can
pose the following query:

[Head| Tail] = [mia, vincent, jules, yolanda].


Head = mia
Tail = [vincent,jules,yolanda]
yes

That is, the head of the list has become bound to Head and the tail of the list has become bound
to Tail. Note that there is nothing special about Head and Tail, they are simply variables. We
could just as well have posed the query:

?- [X|Y] = [mia, vincent, jules, yolanda].


X = mia
Y = [vincent,jules,yolanda]
yes

As we mentioned above, only non-empty lists have heads and tails. If we try to use | to pull []
apart, Prolog will fail:

?- [X|Y] = [].
no

We can extract the head and tail of the following list just as we saw above:
Abeera Afridi
BS(SE)-2018

?- [X|Y] = [[], dead(zed), [2, [b, chopper]], [], Z].


X = []
Y = [dead(zed),[2,[b,chopper]],[],_7800]
Z = _7800
Yes

That is: the head of the list is bound to X, the tail is bound to Y. (We also get the information that
Prolog has bound Z to the internal variable _7800.)

Suppose we wanted to know what the first two elements of the list were, and also the remainder
of the list after the second element. Then we’d pose the following query:

?- [X,Y | W] = [[], dead(zed), [2, [b, chopper]], [], Z].


X = []
Y = dead(zed)
W = [[2,[b,chopper]],[],_8327]
Z = _8327
yes

That is: the head of the list is bound to X, the second element is bound to Y, and the remainder of
the list after the second element is bound to W. W is the list that remains when we take away the
first two elements. So, | can not only be used to split a list into its head and its tail, but we can in
fact use it to split a list at any point. Left of the |, we just have to enumerate how many elements
we want to take away from the beginning of the list, and right of the | we will then get what
remains of the list. In this example, we also get the information that Prolog has bound Z to the
internal variable _8327.

In order to get the second and fourth elements of the list: [[], dead(zed), [2, [b, chopper]], [], Z].
Now, we could find out like this:

?- [_,X,_,Y|_] = [[], dead(zed), [2, [b, chopper]], [], Z].


X = dead(zed)
Y = []
Z = _9593
yes

The _ symbol (that is, underscore) is the anonymous variable.

The third element of our working example is a list (namely [2, [b, chopper]]). Suppose we
wanted to extract the tail of this internal list, and that we are not interested in any other
information. How could we do this? As follows:

?- [_,_,[_|X]|_] =[[], dead(zed), [2, [b, chopper]], [], Z, [2, [b, chopper]]].
X = [[b,chopper]]
Z = _10087
Yes
Abeera Afridi
BS(SE)-2018

Append

Here’s how append/3 is defined:

   append([],L,L).
   append([H|T],L2,[H|L3])  :-  append(T,L2,L3).

This is a recursive definition. The base case simply says that appending the empty list to any list
whatsoever yields that same list, which is obviously true.

But what about the recursive step? This says that when we concatenate a non-empty list [H|T]
with a list L2 , we end up with the list whose head is H and whose tail is the result of
concatenating T with L2 . It may be useful to think about this definition pictorially:

Input: [ H ∣  T   ] +  L2  
Result: [ H ∣ T + L2 ]

For Example

?- append ([a,b,c],[1,2,3],X).
  
   X =  [a,  b,  c,  1,  2,  3]
   yes

The basic pattern should be clear: in the first four lines we see that Prolog recurses its way down
the list in its first argument until it can apply the base case of the recursive definition.

Member

One of the most basic things we would like to know is whether something is an element of a list
or not. When given as inputs an arbitrary object X and a list L, tells us whether or not X belongs
to L. The program that does this is usually called member, and it is the simplest example of a
Prolog program that exploits the recursive structure of lists. Here it is:

member(X,[X|T]).
member(X,[H|T]) :- member(X,T).

That’s all there is to it: one fact (namely member(X,[X|T])) and one rule (namely member(X,[H|
T]) :- member(X,T)). But note that the rule is recursive. The first clause (the fact) simply says: an
object X is a member of a list if it is the head of that list. The second clause says: an object X is
member of a list if it is a member of the tail of the list.
Suppose we posed the following query:

?- member(yolanda,[yolanda,trudy,vincent,jules]).
Abeera Afridi
BS(SE)-2018

Prolog will immediately answer ‘Yes’.

Length of a List
Suppose if we want to find the length of a list
size([],0).
size([H|T],N) :- size(T,N1), N is N1+1.

Example:
For example if we define a predicate which takes a list of non-negative integers as its first
argument, and returns the maximum integer in the list as its last argument. We’ll use an
accumulator. which will keep track of the highest integer found so far. If we find a higher value,
the accumulator will be updated to this new value. When we call the program, we set
accumulator to an initial value of 0. Here’s the code. Note that there are two recursive clauses:

accMax ([H|T], a, Max):- H > A, accMax(T,H,Max).

accMax([H|T],A,Max) :- H =< A, accMax(T,A,Max).

accMax([],A,A).

The first clause tests if the head of the list is larger than the largest value found so far. If it is, we
set the accumulator to this new value, and then recursively work through the tail of the list. The
second clause applies when the head is less than or equal to the accumulator; in this case we
recursively work through the tail of the list using the old accumulator value. Finally, the base
clause unifies the second and third arguments; it gives the highest value we found while going
through the list to the last argument. Here’s how it works:

accMax([1,0,5,4],0,_5810)
accMax([0,5,4],1,_5810)
accMax([5,4],1,_5810)
accMax([4],5,_5810)
accMax([],5,_5810)
accMax([],5,5)
Abeera Afridi
BS(SE)-2018

OBJECT: Learning how to manipulate list in Prolog

How will prolog respond to the following queries?


 append([a, b, c], [d, e, f], Result).

[a,b,c,d,e,f]

 append(ListLeft, ListRight, [a, b, c]).


 member(Elem, [a, b, c]).

1. Write a program to find out the last element of a list

2. Write a program to find out the reverse of a list.


e.g. reverse([a,b,c], [c,b,a]).

3. Define the following predicate.


a. ordered(List).
Which is true if list is an ordered list of number.
b. sumlist(List,Sum).
Sum is the sum of a given list of numbers

findsum([1,2,3,4,5])
findsum(L):-
sum(L,Sum),
write(\"\\nSum Of Given List : \",Sum).

You might also like