Professional Documents
Culture Documents
PROLOG Assigement
PROLOG Assigement
expert systems
specification language
machine learning
robot planning
automated reasoning
problem solving
?-
Compiler optimization
Any computation can be expressed declaratively as a sequence of state transitions.
As an example, an optimizing compiler with three optimization passes could be
implemented as a relation between an initial program and its optimized form:
program_optimized(Prog0, Prog) :-
optimization_pass_1(Prog0, Prog1),
optimization_pass_2(Prog1, Prog2),
optimization_pass_3(Prog2, Prog).
Quicksort
The quicksort sorting algorithm, relating a list to its sorted version:
In prolog, We declare some facts. These facts constitute the Knowledge Base
of the system. We can query against the Knowledge Base. We get output as
affirmative if our query is already in the knowledge Base or it is implied by
Knowledge Base, otherwise we get output as negative. So, Knowledge Base
can be considered similar to database, against which we can query. Prolog
facts are expressed in definite pattern. Facts contain entities and their
relation. Entities are written within the parenthesis separated by comma (, ).
Their relation is expressed at the start and outside the parenthesis. Every
fact/rule ends with a dot (.). So, a typical prolog fact goes as follows :
Example :
friends(raju, mahesh).
singer(sonu).
odd_number(5).
Explanation :
These facts can be interpreted as :
raju and mahesh are friends.
sonu is a singer.
5 is an odd number.
Key Features :
1. Unification : The basic idea is, can the given terms be made to represent the
same structure.
2. Backtracking : When a task fails, prolog traces backwards and tries to satisfy
previous task.
3. Recursion : Recursion is the basis for any search in program.
Running queries :
A typical prolog query can be asked as :
Query 1 : ?- singer(sonu).
Output : Yes.
Query 2 : ?- odd_number(7).
Output : No.
https://www.albany.edu/~csi311/sample.Prolog.questions.html
Symbolic Computation
A good example of symbolic computation and its problems is symbolic differentiation.
Below is given a set of basic rules of differentiation in a PROLOG format.
deriv(C,X,0) :- constant(C).
deriv(X,X,1) :- !.
deriv(-F,X,-G) :- deriv(F,X,G).
deriv(log(F),X,H*(F^(-1)) :- deriv(F,X,H).
Higher-order programming
A higher-order predicate is a predicate that takes one or more other predicates as
arguments. Although support for higher-order programming takes Prolog outside the
domain of first-order logic, which does not allow quantification over
predicates,[25] ISO Prolog now has some built-in higher-order predicates such
as call/1 , call/2 , call/3 , findall/3 , setof/3 , and bagof/3 .[26] Furthermore, since
arbitrary Prolog goals can be constructed and evaluated at run-time, it is easy to
write higher-order predicates like maplist/2 , which applies an arbitrary predicate to
each member of a given list, and sublist/3 , which filters elements that satisfy a
given predicate, also allowing for currying.[24]
To convert solutions from temporal representation (answer substitutions on
backtracking) to spatial representation (terms), Prolog has various all-solutions
predicates that collect all answer substitutions of a given query in a list. This can be
used for list comprehension. For example, perfect numbers equal the sum of their
proper divisors:
perfect(N) :-
between(1, inf, N), U is N // 2,
findall(D, (between(1,U,D), N mod D =:= 0), Ds),
sumlist(Ds, N).
This can be used to enumerate perfect numbers, and also to check whether a
number is perfect.
As another example, the predicate maplist applies a predicate P to all
corresponding positions in a pair of lists:
maplist(_, [], []).
maplist(P, [X|Xs], [Y|Ys]) :-
call(P, X, Y),
maplist(P, Xs, Ys).
When P is a predicate that for all X , P(X,Y) unifies Y with a single unique
value, maplist(P, Xs, Ys) is equivalent to applying the map function in functional
programming as Ys = map(Function, Xs) .
Higher-order programming style in Prolog was pioneered in HiLog and λProlog.
solve(true).
solve((Subgoal1,Subgoal2)) :-
solve(Subgoal1),
solve(Subgoal2).
solve(Head) :-
clause(Head, Body),
solve(Body).
where true represents an empty conjunction, and clause(Head, Body) unifies with
clauses in the database of the form Head :- Body .
Since Prolog programs are themselves sequences of Prolog terms ( :-/2 is an
infix operator) that are easily read and inspected using built-in mechanisms
(like read/1 ), it is possible to write customized interpreters that augment Prolog with
domain-specific features. For example, Sterling and Shapiro present a meta-
interpreter that performs reasoning with uncertainty, reproduced here with slight
modifications:[29]:330
solve(true, 1) :- !.
solve((Subgoal1,Subgoal2), Certainty) :-
!,
solve(Subgoal1, Certainty1),
solve(Subgoal2, Certainty2),
Certainty is min(Certainty1, Certainty2).
solve(Goal, 1) :-
builtin(Goal), !,
Goal.
solve(Head, Certainty) :-
clause_cf(Head, Body, Certainty1),
solve(Body, Certainty2),
Certainty is Certainty1 * Certainty2.
builtin(A is B).
builtin(read(X)).
% etc.
Turing completeness
Pure Prolog is based on a subset of first-order predicate logic, Horn clauses, which
is Turing-complete. Turing completeness of Prolog can be shown by using it to
simulate a Turing machine:
turing(Tape0, Tape) :-
perform(q0, [], Ls, Tape0, Rs),
reverse(Ls, Ls1),
append(Ls1, Rs, Tape).
symbol([], b, []).
symbol([Sym|Rs], Sym, Rs).
?- turing([1,1,1], Ts).
Ts = [1, 1, 1, 1] ;
History
The name Prolog was chosen by Philippe Roussel as an abbreviation
for programmation en logique (French for programming in logic). It was created
around 1972 by Alain Colmerauer with Philippe Roussel, based on Robert
Kowalski's procedural interpretation of Horn clauses. It was motivated in part by the
desire to reconcile the use of logic as a declarative knowledge representation
language with the procedural representation of knowledge that was popular in North
America in the late 1960s and early 1970s. According to Robert Kowalski, the first
Prolog system was developed in 1972 by Colmerauer and Phillipe Roussel.[5] The
first implementation of Prolog was an interpreter written in Fortran by Gerard Battani
and Henri Meloni. David H. D. Warren took this interpreter to Edinburgh, and there
implemented an alternative front-end, which came to define the “Edinburgh Prolog”
syntax used by most modern implementations. Warren also implemented the first
compiler for Prolog, creating the influential DEC-10 Prolog in collaboration with
Fernando Pereira. Warren later generalised the ideas behind DEC-10 Prolog, to
create the Warren Abstract Machine.
European AI researchers favored Prolog while Americans favored Lisp, reportedly
causing many nationalistic debates on the merits of the languages. Much of the
modern development of Prolog came from the impetus of the Fifth Generation
Computer Systems project (FGCS), which developed a variant of Prolog
named Kernel Language for its first operating system.
Pure Prolog was originally restricted to the use of a resolution theorem prover with Horn
clauses of the form:
Variables in prolog
Variables 2
To ask Prolog to find the course that Turing teaches, enter this:
?- lectures(turing, Course).
Course = 9020 ← output from Prolog
If Prolog can tell that there are no more solutions, it just gives you the ?- prompt for a
new query, as here. If Prolog can't tell, it will let you type ; again, and then if there is no
further solution, report false.
Prolog can find all possible ways to answer a query, unless you explicitly tell it
not to (see cut, later).
Backtracking in Prolog
Course = 9314
Student = jill ;
Course = 9314
Student = henry ;
Prolog solves this problem by proceeding left to right and then backtracking.
When given the initial query, Prolog starts by trying to solve
lectures(codd, Course)
There are six lectures clauses, but only two have codd as their first argument.
Prolog uses the first clause that refers to codd: lectures(codd, 9311).
With Course = 9311, it tries to satisfy the next goal, studies(Student, 9311).
It finds the fact studies(jack, 9311). and hence the first solution: (Course =
9311, Student = jack)
Backtracking in Prolog 2
After the first solution is found, Prolog retraces its steps up the tree and looks
for alternative solutions.
First it looks for other students studying 9311 (but finds none).
Then it
o backs up
o rebinds Course to 9314,
o goes down the lectures(codd, 9314) branch
o tries studies(Student, 9314),
o finds the other two solutions:
(Course = 9314, Student = jill)
and (Course = 9314, Student = henry).
Backtracking in Prolog 3
To picture what happens when Prolog tries to find a solution and backtracks, we draw a "proof
tree":
The first version has a negated test in the second rule (=< vs >). The second
version substitutes a cut in the first rule for the negated test.
Remember, no cuts in the first assignment unless they are essential! Hint: the
first assignment can be done without cuts.
Another cut example 2
The first version has a negated test in the third rule (not(member(First,
Rest))). The second version substitutes a cut in the second rule for the
negated test in the third rule.
| ?- likes(mary,food).
yes.
| ?- likes(john,wine).
yes.
| ?- likes(john,food).
no.
| | |
xxx | |
xxxxx | |
xxxxxxx | |
_________________________________
Here's a sample:
% move(N,X,Y,Z) - move N disks from peg X to peg Y, with peg Z being the
% auxilliary peg
%
% Strategy:
% Base Case: One disc - To transfer a stack consisting of 1 disc from
% peg X to peg Y, simply move that disc from X to Y
% Recursive Case: To transfer n discs from X to Y, do the following:
Transfer the first n-1 discs to some other peg X
Move the last disc on X to Y
Transfer the n-1 discs from X to peg Y
move(1,X,Y,_) :-
write('Move top disk from '),
write(X),
write(' to '),
write(Y),
nl.
move(N,X,Y,Z) :-
N>1,
M is N-1,
move(M,X,Z,Y),
move(1,X,Y,_),
move(M,Z,Y,X).
?- move(3,left,right,center).
Move top disk from left to right
Move top disk from left to center
Move top disk from right to center
Move top disk from left to right
Move top disk from center to left
Move top disk from center to right
Move top disk from left to right
yes
An prolog example using lists:
(a) length of a list
size([],0).
size([H|T],N) :- size(T,N1), N is N1+1.
% or size([_|T],N) :- size(T,N1), N is N1+1.
| ?- size([1,2,3,4],N).
N = 4
yes
| ?- size([bill,ted,ming,pascal,nat,ron],N).
N = 6
yes
| ?- size([a, [b, c, d], e, [f | g], h], N).
N = 5
yes
sumlist([],0).
ssumlist([H|T],N) :- sumlist(T,N1), N is N1+H.
member(X,[X|_]).
member(X,[_|T]) :- member(X,T).
reverse(List, Reversed) :-
reverse(List, [], Reversed).
| ?- myreverse([a,b,c,d],X).
no
| ?- myreverse([a,b,c,d],[d,b,c,a]).
no
| ?- myreverse([a,b,c,d],[d,c,b,a]).
yes
Advantages of Prolog
It tempts you to write things that look logically correct, but that won't run.
The obvious way to write a predicate is unlikely to be efficient. You must know
when a predicate needs to be optimised.
Because it lacks functional notation, predicates can become cumbersome.
f( N, F ) :-
N1 is N - 1,
f( N1, F1 ),
F is N * F1.