Date post: | 04-Jan-2016 |
Category: |
Documents |
Upload: | cody-mcdonald |
View: | 212 times |
Download: | 0 times |
Advanced Features in PrologObjects in Prolog• Object is a collection of attributes. Treating related
information as a single object is similar to records in conventional programming languages.
For instance, an object for address can be defined as address(Number, City, Zipcode, Country).
The entire address is treated as a single object and can be used as an argument of a predicate. Here address is called functor and Number, Street, City, Zipcode and Country are called components which hold actual values.
Consider an example of storing data about a course in two different representations as:
course (logic, monday, 9, 11, saroj, kaushik, block3, room21). (1)
course (logic, time(monday,9,11),
lecturer(saroj, kaushik), location(block3, room21)). (2)
These are two representations of a fact “a lecture course on 'logic', given on Monday from 9 to 11 in the morning by saroj kaushik in block 3, room 21”
In representation (1), there is a relationship between eight items.
In (2) there is a relationship between four objects – a course name, a time, a lecturer and a location.
The four-argument version of course enables more concise rules to be written by abstracting the details that are relevant to the query.
Let us define few useful predicates using representation (2) for course facts.
• teacher_course(L, C) - teacher L teaches a course C.
• teacher_on_day(L, Day, C) - teacher L teaches a course C on day Day.
• duration(C, D) - course C of D duration.
These predicates are defined as follows:teacher_course(L, C) :- course(C,_, lecturer(L,_),_).
teacher_on_day(L, Day, C) :- course( C ,
time(Day, _ , _ ), L , _).
duration(C, D):- course(C, time( -, Start, Finish),_,_), D is Finish – Start.
• Note that we have hidden the details which are not required in particular rule formation by putting underscore ( _ ).
• This is called Data abstraction. We don't have definite rules to decide when to use structured data or not.
Query: Who teaches logic course?
Goal: ?- teacher_course(L, logic).
?- teacher_course(L, logic).
?- course(logic, _, lecturer(L,_), _ ).
{L = saroj}
succeeds Answer: L = saroj
Query: Which course does saroj teach?
Goal: ?- teacher_course(saroj, C).
?- teacher_course( saroj, C).
?- course(C, _, lecturer(saroj, _), _ ).
{ C = logic}
succeeds Answer: C = logic
Query: Which day does saroj kaushik teach logic course?
Goal: teacher_on_day(lecturer(saroj, kaushik), X, logic).
?- teacher_on_ day(lecturer(saroj, kaushik), X, logic).
?- course( logic, time(X, _ , _ ), lecturer(saroj, kaushik), _ ).
{X = monday}
succeeds
Answer: X = monday
• The representation of time can be changed without affecting those rules which do not inspect time.
Binary Trees in Prolog• A binary tree is a finite set of elements that is
either empty or is partitioned into three disjoint subsets.
• The first subset contains a single element called the root of a tree.
• The other two subsets are binary trees themselves called left subtree and right subtree of the original binary tree.
• Each element of a binary tree is called a node having three arguments namely, Value, Left_subtree and Right_subtree.
• The binary tree in Prolog is represented by tenary functor, say,
b_tree(Value, Left_subtree, Right_subtree),• The empty binary tree is represented by an atom
called void. Let us represent the following binary tree using above notation.
root
30
25 60
10 70
• Prolog representation of above tree:
b_tree(30,b_tree(25, b_tree(10, void, void), void), b_tree(60, void, b_tree(70, void, void)))
• Binary trees are manipulated in the similar way as the lists are done. Binary tree can also be used as an argument of a predicate just as list and object are used.
Traversal of Binary Trees
• Binary trees are traversed using recursion, mainly, in preorder, inorder and postorder. Preorder Traversal: visit root, traverse left
subtree in preorder, right subtree in preorder. Inorder Traversal: traverse left subtree in
inorder, visit root and right subtree in inorder. Postorder Traversal: traverse left subtree in
postorder, right subtree in postorder and visit root.
Prolog program for preorder traversal as:
/* pre_btree(T, Y)- Y is unified with a list of nodes obtained by traversing T in preorder.*/
pre_btree( void, [ ]). (1)
pre_btree(b_tree(X, L, R), Y):- pre_btree(L, L1), pre_btree(R, R1),
append([X|L1], R1, Y). (2)
• Membership program
mem_btree(X, b_tree(X, L, R)).
mem_btree(X, b_tree(Y, L, R)) :- mem_btree(X, L).mem_btree(X, b_tree(Y, L, R)) :- mem_btree(X, R).
Goal: ?- mem_btree(10, b_tree(35, b_tree(25, b_tree(10,void,void),void),b_tree(62, void, void))).
Incomplete Data Structure• Data structures which are incomplete or having
holes are useful in many applications. Applications will be discussed later.
• Incomplete list is an example of such structures. For example, [1,2,3 | X] is an incomplete list whereas [1,2,3,4] is a complete list.
• First we will discuss difference list, an alternative data structure for representing a list.
• Consider a complete list [1, 2, 3]. We can represent it as the difference of the following pair of lists.
[1, 2, 3, 5, 8] and [5, 8] [1, 2, 3, 6, 7, 8, 9] and [6, 7, 8, 9] [1,2,3] and [ ].
Each of these are instances of the pair of two incomplete lists [1,2,3 | X] and X. We call such pair a difference-list.
We denote the difference list by A-B, where A is the first argument and B is the second argument of a difference-list A-B.
A list [1,2,3] is represented using difference-list as [1, 2, 3 | X] - X . Such representation of list facilitates some of list operations more efficiently.
Example: Concatenating two lists represented in the form of difference lists.
Solution: When two lists represented as difference lists are concatenated (or appended), then we get appended list by simply unifying the appropriate arguments as given below:
• diff_append (A - B, B - C, A - C). If we have to append two lists [1,2,3] and [4,5,6],
then we execute the following goal using difference-list rule given above.
Goal:
?- diff_append([1,2,3 | X] - X , [4,5,6 | Y] - Y, N).
Search tree:
?- diff_append([1,2,3 | X] - X , [4,5,6 | Y] - Y, N).
{A = [1,2,3 | X], B = X = [4,5,6 | Y],
C =Y, N = A-C=[1,2,3,4,5,6 |Y] - Y}succeeds
Answer: X = [4,5,6 | Y]; N = [1,2,3,4,5,6 |Y] - Y This program can not be used for concatenating
two complete lists. Here each list is to be represented using
difference-list notation. There are nontrivial limitations to this representation because the first list gets changed.
Graphical representation of append program for difference lists:
X
X - Y Y
Y - Z
Z
X - Z
The System predicate "cut"• Prolog is non deterministic in nature because even
when a goal has been achieved, the interpreter backtracks to achieve the goal.
Non deterministic system is one which involves choice points more than one of which lead to a successful conclusion.
Prolog provides a system defined predicate called cut (denoted by !) for affecting the procedural behavior of program and to limit the non determinism by preventing interpreter from finding alternative solutions.
When interpreter comes across a 'cut', the effect is that all alternative solutions of the goal waiting to be tried are abandoned thereby reducing the size of search tree.
There are many applications, where the very first solution is of interest, if it exists.
Cut prunes the search tree and hence shortens the path traversed by Prolog interpreter.
It reduces the computation time and also saves storage space.
We can instruct Prolog interpreter to discard remaining solutions obtained on backtracking by using 'cut'. Semantically 'cut' always succeeds.
Such controls given to user changes the execution model of Prolog. Pure Prolog program is a logic program with specific ordering of clauses in the program and sub goals in the body of a clause.
These primitives change the normal execution behavior of pure Prolog.
Operational Behavior of Cut • If a goal G is unified with head of a rule
containing 'cut' in its body then,– if 'cut' is crossed while satisfying the sub goals in
the body, then generation of alternative solutions are debarred using rules with the similar head occurring below that rule i.e., a cut prunes all the rules below it.
– If a goal G fails after crossing a 'cut', then no alternative rules are tried and goal fails completely.
– If a goal G fails before crossing a 'cut', then alternative rule, if any with G as head is tried to get solutions.
The cut prunes all alternative solutions to the conjunction of sub goals which appear to the left of 'cut' in the rule body.
The cut does not affect backtracking amongst the sub goals to the right of cut in the rule body. They can produce more than one solutions.
If cut is the last sub goal in a rule , then it gives atmost one solution.
• To illustrate cut more clearly, let us consider following rules:
G :- A, B, C, !, D, E, F. (1)
G :- P, Q, R. (2)
Important Uses of Cut• Program using cuts operates faster because it does
not waste time in satisfying those sub goals which will never contribute to the solutions.
• Program may occupy less of memory space because search tree is cut down and does not generate redundant branches.
• If we want to tell a Prolog interpreter that it has found a right rule for a particular Goal, then cut is used. Here the cut says "if you get this far, you have picked up the correct rule for this goal”.
Example: Write a program that lists the users and library facilities open to them according to the following scheme.
facilities
basic additional
Reference EnquiryBorrowing Inter library loan
open to all users open to only those users who do not have
any book overdue
Solution:list (U, F) :- user (U), facility (U, F). (1)
facility(U, F):- overdue (U, B), !, basic (F). (2)
facility (U,F) :- general ((F). (3)
basic ( ‘reference’).
basic (‘inquiries’).
general (F) :- basic (F). (4)
general (F) :- additional (F). (5)
additional (‘borrowing’).
additional (‘inter library loan’).
overdue ('S. K. Das', logic).
user ('S. K. Das'). user ('Rajan').
• Let us consider another use of cut. In Prolog, the rules are of if-then type.
• If we are interested in implementing if-then-else type of rule in Prolog, then we can make use of cut to do that. Define a predicate named as if_then_else as follows:
/* if_then_else(U, Q, R) - succeeds by solving Q if U is true else by solving R. */
if_then_else(U, Q, R) :- U, !, Q.
if_then_else(U, Q, R) :- R.• Operationally it means that "prove U and if
succeeds, then prove Q else prove R".
• Declaratively, the relation if_then_else is true if U and Q are both true or if U is not true and R is true.
Types of Cut• There are two types of cuts viz., green cut and red
cut.• Green cut : It does not affect the solution but
affects the efficiency of the Prolog program. • Removal of such cut does not change the meaning
of the program.
Example: Write Prolog program for merging two ordered lists.
/* merge(X, Y, Z) - Z is obtained by merging ordered lists X and Y. */
merge( [X|X1], [Y|Y1], [X|Z] ) :- X < Y, !,
merge(X1, [Y|Y1], Z).
merge( [X|X1], [Y|Y1], [X, Y|Z] ):- X = Y, !,
merge(X1, Y1, Z).
merge( [X|X1], [Y|Y1], [Y|Z] ) :- X > Y,
merge( [X|X1], Y1, Z).
merge(X, [ ], X).
merge( [ ], Y, Y).
• If we remove cuts from the rules, then the solutions are not affected and program does not change.
Red cut: The cut whose removal from the program changes the meaning of the program.
• Consider two versions of the programs for finding maximum of two numbers. Version I
% max(X, Y, Z) – Z is unified with maximum of X and Y.
max(X, Y, Z):- X Y, !, Z = X . (1)
max(X, Y, Y) . (2)Goals: ?- max(5, 4, 4). Answer: No
?- max (5, 4, 5). Answer: Yes
• If the cut is deleted from the rule, then we will not get correct answer.
Version 2: If the above program is rewritten as follows, then the cut used here becomes a green cut and its removal will not affect the solution (verify).
max(X, Y, Z) :- X Y, !, Z = X.max(X, Y, Y) :- X > Y.
Fail predicate If we want to force a rule to fail under certain
conditions, then built in predicate called fail is used in Prolog. Predicate fail tells Prolog interpreter to fail a particular goal and subsequently forces backtracking.
All the sub goals defined after fail will never be executed.
Hence predicate fail should always be used as the last sub goal in a rule. It is to be noted that rule containing fail predicate will not produce any solution.
Consider the following few examples to illustrate the use of fail predicate.
listing(Name, Address) :- emp(Name, Address).
emp(ram, cse).
emp(rita, maths).
emp(gita, civil).
Goal: ?- listing(Name, Address).• All possible solutions obtained on executing above
goal are: Name = ram , Address = cse;
Name = rita , Address = maths;
Name = gita , Address = civil;
The desired results are obtained by normal backtracking of Prolog (finds alternative solutions). Here the variable names are displayed along with the values.
While developing large software, we might not like to display variable names along with their values but rather values only.
In order to achieve this, we will change the program as follows and use some more system defined predicates called write and nl which succeed by writing argument values and creating new line respectively along with fail predicate.
listing :- write(‘Name‘), write( ‘ Address’), nl,
emp(Name, Address), write (Name), write(' '),write(Address), nl, fail. (1)
emp(ram, cse).
emp(rita, maths).
emp(gita, civil).
Goal: ?- listing
Name Address
ram cse
rita maths
gita civil
Cut and Fail Combination• If cut is used in conjunction with fail predicate and
if control reaches fail in the body of a rule after crossing cut (!) , then the rule fails and no solution is displayed.
• The reason being that the rules following current rule will not be tried because of cut. The cut-fail combination is a technique that allows early failure.
• A rule with a cut-fail combination says that the search need not proceed.
• Consider the following definitions of the rules using cut and fail combination.
X :- X1, !, fail. (1)
X :- X2, X3. (2)
Goal: ?- X.• If X1 succeeds, then rule (1) fails and rule (2) will
not be tried.• If X1 fails, then rule (2) will be tried on
backtracking.
• Cut and fail combination is also useful for expressing negative facts. For example, "john does not like snakes" could be expressed by the following rule and fact.
like(john, snake) :- !, fail.
like(john, X).• This coding of rules state that "John likes
everything except snake" which implies that "john does not like snakes".
Goal: ?- like(john, snake). Answer: no
Goal: ?- like(john, dog). Answer: yes
Negation as Failure• Horn clauses are incomplete version of FOPL
because of the limitation of one positive literal in a clause.
Here we describe an extension to the LP computation model that allows a limited use of negative information in the program.
A goal not(G) is said to be a logical consequence of a program P if G is not a logical consequence of P. In other words, if goal G can not be shown to be true, then infer the truth of not(G).
A goal not(G) is implied by a program P by the negation as failure rule. The cut-fail combination can be used to implement a version of negation as failure.
It is difficult to implement negation both efficiently and correctly.
not(G) :- G , !, fail.
not(G).• The cut ensures that if G succeeds, the second
clause will not be attempted and if G fails, then cut is not activated and so second clause is tried and it succeeds.
• Therefore, if goal G succeeds, then not(G) fails and if G fails, then not(G) succeeds.
Goals:
?- not(2 < 4). Answer: No
?- 2 < 4 Answer: No• It is a good programming style to replace cut by
the use of not if possible because the programs containing cuts are generally harder to understand.
• The rule using not predicate is more readable and gives clear semantic interpretation of the rule but at times could be computationally expensive.
• Predicate if_then_else can be implemented using using not predicate instead of cut.
if_then_else(P, Q, R) :- P, Q.
if_then_else(P, Q, R) :- not(P), R.• Here the goal P have to be computed again while
trying second rule of if_then_else.
• The Prolog rule P :- Q1, Q2, ...,Qn expresses only if condition for P and it says nothing about other conditions under which P can be true.
• Negation as failure introduces a closed world in the limited sense. Every thing not stated is taken to be false.
Logical Limitations of Prolog• Prolog does not allow disjunction ('or' ) of facts or
conclusion such as
"If car does not start and the light does not come on, then either battery is down or problem with
ignition or some electric fault"
• Such rules can not be expressed straight away in Prolog.
Prolog does not allow negative facts or conclusions e.g., not(a) :- b ; not(c) etc are not valid in Prolog.
Prolog does not allow facts, rules having existential quantifications.