Sunteți pe pagina 1din 34

LAB#1

UNDERSTAND BASIC OF PROLOG


Getting computers to communicate with us in human languages like English, either by printing on a
computer terminal, understanding things we type on a computer terminal, generating speech, or
understanding our speech (natural language);
Getting computers to remember complicated interrelated facts, and draw conclusions from them.
If we want computers to act intelligent, we must help them. We must tell them all the commonsense
knowledge. Now there are many different kinds of knowledge. Without getting deep into philosophy
(or specifically epistemology, the theory of knowledge), there are two main kinds: facts and reasoning
procedures. Facts are things true about the world, and reasoning procedures (or inferences) are ways to
follow reasoning chains between facts. Since facts are easier to represent than procedures.
The program logic of Prolog is expressed in terms of relations, represented as facts and rules. A
computation is initiated by running a query over these relations.
HOW MANY FACTS DO WE NEED?
Infinity of facts is true about the world. How then do we decide, which to tell a computer?
Generally, we must decide that what we want from computer to do, then make sure to tell the
computer every fact that might be relevant to that behavior. Libraries of useful facts for particular
subjects will help. But smarter you want the computer to be, more facts you must tell it.
SEMANTIC NETWORKS
Pictures can make a complicated set of facts a lot clearer. Theres a simple pictorial way
(labeled directed graph) to show the predicate expressions. Weve been discussing the semantic
network. But there is one restriction on it: semantic networks can only directly represent predicates
of two arguments (so type predicate must be in two argument form).
EXAMPLE:
a_kind_of(khaiber, ship).
a_kind_of(tipu_sultan, ship).
part_of(khaiber, pak_navy).
part_of(tipu_sultan, pak_navy).
part_of(pak_navy,pak_government).
a_kind_of(pak_govrnment,government).
color (ship, gray).
location(khaiber, 15n35e).
has(pak_government, civil_service_system).

1 | Page

EXAMPLE OF SEMANTIC NETWORK

OBJECT:
Draw a semantic network representing the following facts, and implement following fact using
Prolog:
Ships are things.
Carriers are ships.
Ships have a position.
Ships have a crew.
Carriers have planes.
Planes are things.
A crew consists of people.
People are things.

2 | Page

LAB#2
TEST THE EVALUATION OF GOALS, USING UNIFICATION AND
BACKTRACKING
Unification is the process of matching two predicates and assigning free variables to make the
predicates identical. This mechanism is necessary so that Prolog can identify which clauses to call and
bind values to variables. These are the major points about matching (Unification) presented in this
session.
When a new call is made, a search for a match to that call also begins at the top of the program
When a call has found a successful match, the call is said to return, and the next sub goal in turn can
be tried.
Once a variable has been bound in a clause, the only way to free that binding is through backtracking.
Backtracking is the mechanism that instructs Prolog where to go to look for solutions to the program.
This process gives Prolog the ability to search through all known facts and rules for a solution. There
are four basic principles of backtracking given in this session:
Sub goals must be satisfied in order, from top to bottom.
Predicate clauses are tested in the order they appear in the program, from top to bottom.
When a sub goal matches the head of a rule, the body of that rule must be satisfied next. The body of
the rule then constitutes a new set of sub goals to be satisfied.
A goal has been satisfied when a matching fact is found for each of the extremities (leave) of the goal
tree.
A call that can produce multiple solutions is non-deterministic, while a call that can produce one and
only one solution is deterministic.
Example 1:
factorial(0,1).
factorial(X,Y) :-

X1 is X - 1, factorial(X1,Z),
Y is Z*X,!.
Decomposition (factorial(4,Fact)):
X1 is 3, (X1 is 2, (X1 is 1, (X1 is 0, (Z=1), Y ==1 is X==1 * Z==1), Y==2 is X==2 * Z==1), Y==6 is
X==3 * Z==2), Y==24 is X==4 * Z==6)
X is decreasing step by step
Each Y has the value of Z form previous step.

3 | Page

Example 2:
talks_about(A,B):-knows(A,B).
talks_about(P,R):-knows(P,Q),talks_about(Q,R).
Example 3:
Facts:
parent(john,paul). /* John is Paul's parent */
parent(paul,tom). /* Paul is Tom's parent */
parent(tom,mary)./* Tom is Mary's parent */
Rules:
ancestor(X,Y) :- parent(X,Y).
ancestor(X,Y) :- parent(X,Z), ancestor(Z,Y).

Query:
Execution scheme for the query
ancestor(john,tom).
CALL ancestor(john,tom).
CALL parent(john,tom).
FAIL parent(john,tom).
CALL parent(john,Z).
TRY Z=paul (Unification)
CALL ancestor(paul,tom).
CALL parent(paul,tom). (Recursion)
SUCCEEDS parent(paul,tom).
SUCCEEDS ancestor(paul,tom).
SUCCEEDS with Z=paul
SUCCEEDS ancestor(john,tom).
GOAL:
Name of few countries with
population is given, define a general
rule that Print the name of countries
having population greater than 10
million.
c
o
u
n
t
r
4 | Page

y
(
e
n
g
l
a
n
d
,
3
e
7
)
.
c
o
u
n
t
r
y
(
f
r
a
n
c
e
,
2
.
3
e
7
)
.
c
o
u
n
t
r
y
(
g
5 | Page

e
r
m
a
n
y
,
1
.
6
e
7
)
.
c
o
u
n
t
r
y
(
d
e
n
m
a
r
k
,
2
.
4
e
6
)
.
c
o
u
n
t
r
y
(
c
a
n
6 | Page

a
d
a
,
7
.
3
e
6
)
.

7 | Page

LAB#3
TO TEST A SIMPLE DISEASE DIAGNOSIS SYSTEM A CASE STUDY
go :write(What is the name of Patient?), read(Patient),nl,
hypo(Patient, Disease),
write(Patient),write( probably has ),write(Disease),nl.
go:write(Sorry I am unable to diagnose the Disease.),nl.
hypo(Patient,flu):-sym(Patient,fever), sym(Patient,cough).
hypo(Patient,headche):-sym(Patient,bodypain).
sym(Patient,fever):write( Does ),write(Patient),write( has fever (y/n)?), res(R),R=y.
sym(Patient,cough):write(Does ),write(Patient),write( has cough (y/n)?), res(R),R=y.
sym(Patient,bodypain):write(Does ),write(Patient),write( has bodypain (y/n)?), res(R),R=y.
res(R):-read(R),nl.

LAB#4
WORKING WITH USER DEFINED FUNCTIONS
Function1:
cube :read(X), calc(X).

/* read X then query calc(X). */

calc(stop) :- !.
/* if X = stop then it ends */
calc(X) :- C is X * X * X, write(C),cube. /* calculate C and write it then ask again cube. */
Function2:
evaluate(Expression, Answer :- Answer is Expression).
Query:
?- evaluate(2*9,Ans).
Ans = 18
Yes
Function3:
Loops: (equivalent to While Do like C) test
:- repeat,
write('Please enter a number'),
read(X),

(X=:=42).
In this example the program will ask you to enter a number until you enter 42.
Fabonacii Series:
go(N):- write(0),nl, write(1),nl, go(0,1,N).
go(_,_,0):- !. go(A,B,C):- A1 is A,B1 is B,

C1 is A1+B1, write(C1),nl, NewC is C-1, go(B1,C1,NewC).


fab:- write('Input No. : '), read(N),
go(N).

OBJECT :
Make a rule for generating palindrome numbers
1, 11, 22, 33, 44, 55, 66, 77, 88, 99, ..

LAB#5
TO WORK WITH THE IMPLEMENTATION OF PROLOG DATABASE (I.E.,
FACTS AND RULES WHICH MAKE RELATIONAL DATABASE)
Databases in Prolog are bit different from other (procedural) databases. In Prolog there are two types
of databases: static databases and dynamic database.
A static database is one whose components (field records) information, as well as rules about their
relationships is stored in memory at run time.
A dynamic database is composed of facts gathered by the user during program execution. These facts
re stored in a separate (dynamic) database. A dynamic database is stored in memory along with a static
database; more memory is needed here.
You can name facts section (which creates a corresponding internal domain). Your program can have
multiple facts sections, but each one must have a unique name.
With the standard predicates assert, asserta, assertz, and consult, you can add facts to the facts section
at run time. You can remove such facts at run time with the standard predicates. You can remove such
facts at run time with the standard predicates retract and retractall.
You can save predicates from facts section to a file and can consult or reconsult it in program. You
can create or edit such a fact file with an editor, and then insert facts from the file into your running
program with consult.
You can call database predicates in your program just like you call other predicates.

You can handle facts as terms when using the domain internally, generated for a database section.
It is simple to build queries using references and relationships.
Example:
Suppose department of an educational institute stores this information for each student.
student number, last name, first name, street, city, state, major, minor, class taken, time, class credit
hours, class meeting time, class grade, total credit hours, total honor points, and honor point average a
database system should be able to handle queries about any combination of fields pertaining to an
individual student; which Prolog can do very well. The above attributes are divided into three relations
(tables): student, class, and major, having the formats following and with key fields indicated by all
capital letters.
1 NF OF DATABASE:
student( STUDENT_NUMBER, Last_name, First_name, Street_address, City, State)
class(CLASS_NAME, STUDENT_NUMBER, Credit_hours, Meeting_time, Grade)
major(STUDENT_NAME, Major_subject, Minor_subject)

RECORDS:
student(1001,
student(1022,
student(1099,
student(2000,
student(3022,
student(4001,
student(5000,
student(5055,
student(6000,
student(6087,
student(7001,
student(7555,
student(8005,

brown, sam, happy_way,marquette, mi).


andrews, andy, kin_olaf_st, marquette, mi).
cummings, maria, gray_rd, marquette, mi).
xylon, fed, greenview_ave, lansing, mi).
franklin, georgia, burrow_way, detroit, mi).
green, nancy, greenview_rd, mt_pleasant, mi).
green, sam, greenview_rd, mt_pleasant, mi).
pershing, xerexes, happy_way, marquette, mi).
petersen, olaf, blackstone_blvd, detroid, mi).
sklarson, bill, center_blvd, milwaukee, wi).
timmons, timmy, twin_st, minneapolis, mn).
young, chiquita, felton_st, philadelphia, pa).
herring, cremora, briggs_blvd, Detroit, mi).

class(elem_math, 1001, 3, m900).


class(elem_math, 2000, 3, m900).
class(elem_math, 4001, 3, m900).
class(elem_math, 7555, 3, m900).
class(elem_math, 8005, 3, m900).
class(intro_comp, 1001, 3, m1100).
class(intro_comp, 2000, 3, m1100).
class(intro_comp, 5000, 3, m1100).
class(intro_comp, 6087, 3, m1100).
class(intro_comp, 7555, 3, m1100).
class(english_comp, 3022, 4, t800).
class(english_comp, 4001, 4, t800).
class(english_comp, 5000, 4, t800).
class(english_comp, 6000, 4, t800).
class(english_comp, 6087, 4, t800).
class(english_comp, 7001, 4, t800).
class(english_comp, 8005, 4, t800).
class(intro_bus, 1001, 3, t1200).
class(intro_bus, 4001, 3, t1200).
class(intro_bus, 5000, 3, t1200).
class(intro_bus, 6000, 3, t1200).
class(intro_bus, 7001, 3, t1200).
class(intro_bus, 7555, 3, t1200).

major(1001,
major(1022,
major(1099,
major(2000,
major(3022,
major(4001,
major(5000,
major(5055,
major(6006,
major(6087,

business, economics).
business, economics).
business, economics).
computer_sci, math).
accounting, business).
business, accounting).
computer_sci, bussiness).
computer_sci, economics).
economics, accounting).
economics, computer_sci).

major(7001, accounting, economics).


major(7555, accounting, business).
major(8005, economics, accounting).

OBJECTS:
1. Find the complete address (street, city, state) of student Sam Brown. Find the
student number of student Xeroxed Pershin.
2. Find Olaf Petersens major and minor fields.
3. List the names off all students living in Michigan (MI).
4. List the student numbers of all Lower Peninsula students (i.e., students living in
Michigan, but not in Marquette).
5. List the student numbers of all students taking elem_math. List the names of
all students taking elem_math.
6. List the names of all students with business as their major field.
7. List the names and address of all students with economics as their minor field.
8. List the names of all students taking a class at noon on Tuesdays (t1200).

QUERIES FOR ABOVE OBJECTS:


1. student(_, brown, sam, Street, City, State).
student(Student_number, pershing xerxes, _, _, _).
2. student(Student_number, petersen, olaf, _, _, _), major(Student_number,
Major, Minor).
3. student(_, Lastname, Frstname, _, _, mi).
4. student(Student_number, _, _, _, City, mi), City /= marquette.
Or
student(Student_number, _, _,_ , City, mi), not(City = marquette).
5. class(elem_math, Student_number, _, _).
class(elem_math, Student_number, _, _), student(Student_number,
Lastname, Firstname, _, _, _).
6. student(Student_number, Lastname, Firstname, Street, City, State),
major(Student_number, business, _).
7. student(Student_number, Lastname, Firstname, Street, City , State),
major(Student_number, _, economics).
8. class(_, Student_number, , t1200), major(Student_number, Lastname,
Firstname, _, _, _).

LAB#6
TO UPDATE/ DELETE RECORDS ON RUN-TIME USING ASSERT AND
RETRACT.

Make a fact file for update/ delete operations and consult it, then assert a fact which is being
used in the program which is to be updated i.e., class (_, _, _); at console to make it to use
dynamically at run time. This operation defines a dynamic rule.
Example:
?- assert(class(1001, umer, g)).
?- assert(class(1002, ali, g)).
?- assert(class(1003, mariam, g)).
?- assert(class(1004, zia, g)).
?- retract(class(1001,umer,g)).
?- asserta(class(1005,ali,g)).
?- retractall(class(_,ali,_)).

OBJECT:
assign_grade:write('Enter Student\'s number: '),read(ID),nl,class(X,ID,Y,Z),
write('current record'),nl,
write('--------------'),nl,
write('Course Name:'),tab(5),write(X),nl,
write('Credit hour:'),tab(5),write(Y),nl,
write('Class Timing:'),tab(5),write(Z),nl,
write('Enter new credit hour: '),read(Grade),
call(retract(class(X,ID,Y,Z))),
call(assert(class(X,ID,Grade,Z))),nl,
class(Name,ID,NewGrade,Z),
write('updated record'),nl,
write('--------------'),nl,
write('Name: '),tab(5),write(Name),nl,
write('New Credit hour: '),tab(5),write(NewGrade).
Hint:
Add built in function :-dynamic class/4 before defining facts class.

LAB#7
TO WORK WITH FILES FOR READING AND WRITING.
Files can be handled in Prolog using following built-in predicates.
see(F)

/* File F becomes the current input stream. */

seeing(F)
seen
tell(F)
telling(F)
told
close(F)
rename(F,N)

/* F is unified with the name of the current input file. */


/* Closes current input stream. */
/* File F becomes the current output stream. */
/* F is unified with the name of the current output file. */
/* Closes the current output stream. */
/* File F, currently open for input or output, is closed. */
/* If file F is currently open, it is closed and renamed to N. If N is '[]', the file is deleted. */

Some extra file operations:


delete_file
rename_file
size_file Cd
make_directory
delete_directory
rename_directory
Example 1:
seeing(File)
see(File)
read(Data)
seen
File='user' will select the keyboard for the input source

Example 2:
browse(File) :seeing(Old),
see(File),
repeat,
read(Data),
process(Data),
seen,
see(Old),
!

/* save for later */


/* open this file */
/* read from File */
/* close File */
/* previous read source */
/* stop now */

process(end-of-file) :- !.
process(Data) :- write(Data), nl, fail.

LAB#8
TO USE PROLOG LISTS AND LIST MANIPULATION.
List Construction:
The construction of a list is the reverse: take a variable bound to any old list i.e., X=[r, e, d] and add
the element, say, b at the front with:
Result_Wanted = [b|X]
List Destruction:
First, we show how to remove the first element from a list.
[X|Y] = [f,r,e,d] will result in
X=f // The first element of the list is known as the HEAD of the list. Y=[r,e,d]
Recursion using LIST:
print_a_list([]).
print_a_list([H|T]):-

write(H), print_a_list(T).

Lists, for now, can be regarded as special Prolog structures that can be used to represent an ordered
sequence of Prolog terms. For example, here are some legal lists:
[ice_cream, coffee, chocolate]
[a, b, c, c, d, e]
[]
[dog(fido), cat(rufus), goldfish(jimmy)]
[happy(fred),[ice_cream,chocolate],[1,[2],3]]

// a list with three elements (all atoms)


// a list with six elements (all atoms)
// a list with no elements in it (it is an atom)
// a list with three elements (all Prolog terms)
// a list with three elements!

The last example is a little difficult to decipher: the first element is happy(fred), the second is
[ice_cream,chocolate], a list, and the third is [1,[2],3], another list.
Member:
member(X,[X|R]). member(X,[Y|
R]) :- member(X,R).
One can read the clauses the following way, respectively: X
is a member of a list whose first element is X.
X is a member of a list whose tail is R if X is a member of R.
This program can be used in numerous ways. One can test
membership:
?- member(2,[1,2,3]).
Yes

EXAMPLES:
One can generate members of a
list: ?- member(X,[1,2,3]).
X=1;
X=2;
X=
3 ; No
Here is a derivation tree showing how this last goal generated all of the answers.

Each left branch corresponds to a match (unification) against the first clause for 'member' and each
right branch corresponds to a match against the second clause. The sub goal 'member(X,[])' on the
lowest right branch will not match the head of any 'member' clause. In particular '[]' will not unify with
a pattern of the form '[X|R]' because the latter represents a list with at least one element.
We will find many other uses for 'member'. This example query.
?- member([3,Y], [[1,a],[2,m],[3,z],[4,v],[3,p]]).
Y=z;
Y =
p ; No
Suggests a use where one intends to search in order to find elements paired with a specified element.
Here is another, finding elements of a list which satisfy some constraint:
?- member(X,[23,45,67,12,222,19,9,6]), Y is X*X, Y < 100.
X = 9 Y = 81 ;
X = 6 Y = 36 ;
No
The definition for 'member' is usually
written member(X,[X|_]).
member(X,[_|R]) :- member(X,R).
where '_' (underscore) designates a "don't-care" variable, usually called anonymous variables. In
general, such variables have names whose first character is the underscore. In effect, they match any
Prolog term, but no variable binding results from the free match. Notice that this is consistent with the
original intentions of the definition of 'member'. Not having to bind values to anonymous variables
saves a little run-space and run-time

W ri tin g li s t:
w r i t el is t ([ ] ) .
w r i t el is t ([ H |T ] ): - w r i t e( H ), nl , w ri t el is t ( T ) .
W ri tin g revers e li s t:
Method #1 :
rev_list([ ]) .
rev_list ([H |T] ):-rev_list(T),n l,write(H) .
Method #2 :
reverse([X|Y ],Z,W ):-reverse(Y,[X|Z],W ).
reverse([ ],X ,X ) .
This program illustrates Prolog's approach to an important strategy using an accumulating parameter
(the middle variable). To accumulate a list answer until the computation is finished. For example,
consider the following (partial) derivation tree.
? - reverse([ 1, 2 ,3] , [ ] , A )
|
reverse([ 2 ,3] ,[ 1] ,A )
|
reverse([ 3] ,[ 2 , 1] ,A )
|
reverse([ ] ,[ 3, 2 ,1] ,A )
|
true
A = [ 3 ,2 , 1]
OBJECT:
Do these unify? If yes what is the value of free variable after unification?
???????????-

A= [a,d,z,c], A = [H|T].
A=[a,b,c], A= [a|Rest].
A=[pear,grape,orange],A=[C,grape|Rest].
A=[pear,grape,orange],A=[C,orange|Rest].
[a,[]] = [A,B|Rest].
[a]=[One].
A=[a,b,c,d],A=[a,b,X].
A=[a,b,c,d],A=[a,b,X,Y].
[a,b,c,d]=[a,b,X,Y].
[a,[aa,b]] = [A,B|Rest].
[a,[aa,b],c] = [A,B|Rest].

LAB#9
TO WORK WITH MEDICAL DIAGNOSIS USING LISTS
Theory:

cause(disease1,
cause(disease2,
cause(disease3,
cause(disease4,
cause(disease5,
cause(disease6,
cause(disease7,

[symptom1]).
[symptom2]).
[symptom3]).
[symptom1, symptom2]).
[symptom1, symptom3]).
[symptom2, symptom]).
[symptom1, symptom2, symptom3]).

diagnose(Person, Disease):suffers_from(Person, Symptoms),


cause(Disease, Symptoms).

suffers_from(Person, Symptoms):write( Patient name ? ), read(Patient),


write( Give list of symptoms ), read(Symptoms).
hi_doctor:diagnose(Person, Disease),
write(Person),nl,
write(Disease),nl.

LAB#10
TO STUDY SENTENCE PARSING
Sentence parsing architecture:

Sentence

Noun Phrase

Article

Verb Phrase

Noun

Verb

Noun Phrase

Article
The

man

likes

A PROLOG APPLICATION: (%% Rule base:)


parseSentence(X) :- sentence(X,[]).
sentence(Start, End) :- nounphrase(Start, Rest),
verbphrase(Rest, End).
nounphrase([Noun|End],End) :- noun(Noun).
nounphrase([Article, Noun|End],End) :article(Article),
noun(Noun).
verbphrase([Verb|End], End) :- verb(Verb).
verbphrase([Verb|Rest],End) :- verb(Verb),
nounphrase(Rest, End).

%% Facts/ Knowledge
base: article(a).
article(the).
noun(man).
noun(horse).
verb(likes).

the

Noun
horse

%% Queries:
?- parseSentence([the,man,likes,the,horse]). Yes
?- parseSentence ([the,man,likes,the,X]). X =
man ; X = horse
Yes

?- parseSentence ([a,likes,the,X]). No
Parsing a f unction :
parse( X , Y ):-parse( X,Y,_).
parse( X , Y, A ):-Z= . . [X,Y,A],call(Z) .
:-arithmetic_function(hi/1) .
hi(A,C):-C is A*60,print(C ) .

definition in .pl fil e

? - parse(hi,2).120
query Yes

LAB#11
TO STUDY THE GENERATION OF A TRUTH TABLE A CASE STUDY
Truth table maker:
The purpose of this section is to develop a Prolog program for calculating and displaying truth tables

for Boolean expressions involving 'and', 'or', and 'not'. We seek the following kind of program
behavior:
?- tt(x or (not y and z)).
[x,y,z]
x or (not y and z)
----------------------------------[0,0,0]
0
[0,0,1]
1
[0,1,0]
0
[0,1,1]
0
[1,0,0]
1
[1,0,1]
1
[1,1,0]
1
[1,1,1]
1
----------------------------------So, the program will be required to do the following things:
!
!
!
!
!

recognize infix Boolean expressions involving Boolean operations 'and', 'or', and 'not'
find the variables in a Boolean expression
generate an initial truth assignment for as many variables as there is in the expression
evaluate the expression at a particular truth assignment
generate the next truth assignment in binary count-up order

In order to use 'and' and 'or' as infix operators, declarations such as the following will
suffice :- op(1000,xfy,'and').
:- op(1000,xfy,'or').
The 'not' operator may already be recognized by Prolog (as negation as failure), but if not, then the
declaration
:- op(900,fy,'not').
will make 'not' bind more tightly than 'and' and 'or'. Generally, it will probably be better to use
parentheses in the Boolean expressions, rather than trying to figure out a fool-proof precedence
scheme that the program user needs to know about.
To find the variables in a Boolean expression, we propose a Prolog definition whose profile is
find_vars(+The_Expression,+Previously_Found_Variables,-Answer)
indicating that the expression and the previously found variables are supplied on a call, and that the
answer gets "bound" by the program.
find_vars(N,V,V) :- member(N,[0,1]),!.
/* Boolean constants in expression */
find_vars(X,Vin,Vout) :- atom(X),
(member(X,Vin) -> Vout = Vin ;
/* already have */
Vout = [X|Vin]).
/* include
*/
find_vars(X and Y,Vin,Vout) :- find_vars(X,Vin,Vtemp),
find_vars(Y,Vtemp,Vout).
find_vars(X or Y,Vin,Vout) :- find_vars(X,Vin,Vtemp),
find_vars(Y,Vtemp,Vout).
find_vars(not X,Vin,Vout) :- find_vars(X,Vin,Vout).
For example,

?- find_vars(x and (y or x), [], V).


V = [y,x]
Notice that find_vars will produce a list of variables in their right-to-left occurrence order in the
original expression. Why? We will reverse this list of variables in the main program.
To generate the initial truth assignment, use the list of variables as a guide:
initial_assign([],[]).
initial_assign([X|R],[0|S]) :- initial_assign(R,S).
For example,
?- initial_assign([w,x,y,z],A).
A = [0,0,0,0]
The program to generate the successor truth assignment is as follows:
successor(A,S) :- reverse(A,R),
next(R,N),
reverse(N,S).

For example, what is proposed should work like this?


[0,1,0,1] == reverse ==> [1,0,1,0] ==next==> [0,1,1,0] ==reverse==>[0,1,1,0]
where the point of reversing is that it would be easier to describe binary addition to the front of a list,
rather than to the end of a list. The predicate 'next' will be a recursive N-bit binary adder, where N is
the number of variables in the Boolean expression.
next([0|R],[1|R]). next([1|R],
[0|S]) :- next(R,S).

Now, to evaluate the Boolean expression, a recursive-descent evaluator should be easy to define. We
propose the following profile:
truth_value(+Expression,+Variable_List,+Assign_List,-Truth_Value) so
that we can expect to be able to use this in the following way.
?- truth_value(not x or y, [x,y],[1,0],V.
V=0
Here is a definition for 'truth_value'.
truth_value(N,_,_,N) :- member(N,[0,1]).
truth_value(X,Vars,A,Val) :- atom(X),
lookup(X,Vars,A,Val).

truth_value(X and Y,Vars,A,Val) :- truth_value(X,Vars,A,VX),


truth_value(Y,Vars,A,VY),
boole_and(VX,VY,Val).
truth_value(X or Y,Vars,A,Val) :- truth_value(X,Vars,A,VX),
truth_value(Y,Vars,A,VY),
boole_or(VX,VY,Val).
truth_value(not X,Vars,A,Val) :- truth_value(X,Vars,A,VX),
boole_not(VX,Val).

The 'lookup' predicate uses positional association.


lookup(X,[X|_],[V|_],V). lookup(X,[_|Vars],[_|
A],V) :- lookup(X,Vars,A,V).

Now we need the driver to force the generation of the entire truth table. The intention is to construct
the truth table by means of first finding the variables (already discussed), calculating an initial truth
assignment (also already discussed), and then filling out the table row-by-row, or, in a picture
tt(E) :- find_vars(E,[],V),
reverse(V,Vars),
initial_assign(Vars,A),
write(' '), write(Vars), write(' '), write(E), nl,
write('-----------------------------------------'), nl,
write_row(E,Vars,A),
write('-----------------------------------------'), nl.
where write-row will call itself to write the next row of the truth table (if there should be a next row in
the table).
write_row(E,Vars,A) :- write(' '), write(A), write(' '),
truth_value(E,Vars,A,V), write(V), nl,
(successor(A,N) -> write_row(E,Vars,N) ; true).

The 'write_row' definition relies of the failure of successor when A == [1,1,1,...,1]. Lastly, we supply
the truth tables.
boole_or(0,0,0). boole_not(0,1). boole_or(0,1,1). boole_not(1,0).
boole_or(1,0,1).
boole_and(0,0,0).
boole_or(1,1,1).
boole_and(0,1,0).
boole_and(1,0,0).
boole_and(1,1,1).
OBJECT:
Add the Boolean operations 'nand', 'nor', and 'xor' to the program.

LAB#12
TO WORK WITH arithmetic_fuction/{arity-1} AND op/1
PARSING IN PROLOG
Making user defined functions:
Example 1:
:-arithmetic_function(myFunction/1).
myFunction(A,B):-B is A+1.
OPERATOR OVERLOADING:
op(Priority,Appearence,Name)

|
|

-- xfy, yfx, xfx, fx, fy, xf, yf


-- the higher number the priority has, the lower
priority op(1200,xfx,':-').
op(1200,fx,[:-,?-]).
op(1100,xfy,';').
op(1000,xfy,',').
op(700,xfx,[=,is,<,>,=<,>=,==,=:=]).
op(500,yfx,[+.-]). op(500,fx,
[+,-,not]). op(400,yfx,[*,/,div]).
op(300,xfx,mod).
Instead of explaining the meaning of above definition, look at the following example.
op(400,yfx,'*'). % a*b*c means ((a*b)*c)
op(500,yfx,'+').
op(500,yfx,'-'). % be careful a-b-c means ((a-b)-c)
op(700,xfx,'=') % it is not possible to write a=b=c
Example 3:
?- op(100,yfx,'+').
Yes
?- op(200,yfx,'*').
Yes
?- Y is 2+2*2.
Y=8
Yes

Example 4:
?op(9,yf,'-').
Yes
- (A,B) : - S is A - B. [Definition in .pl
file] ?- -(4,3).
Yes
?- X is -(4,3).
X=1
Yes
?- X is -(4,-(2,0)).
X=2
Yes
?- X is -(-(2,0),(3,4)). X = 3
Yes
Example 5:
?- op(100,xfx,'plus').
?- Asserta( (X plus Y :- Z is X+Y,write(Z)) ).
?- 2 plus 4.
6
Yes
Example 6:
:- op(25,xf,[minutes]).
:- arithmetic_function(minutes/1).
minutes(M,S) :-S is M * 60.
Query:
?- Time is 3 minutes.
Time = 180
yes.
Example 7:
?- op(100,yfx,'+').
Yes

Example 8:
?- op(200,yfx,'*').
Yes
?- Y is 2+2*2.
Y=8
Yes

Example 9:
?- op(100,xfx,'plus').
?- Asserta( (X plus Y :- Z is X+Y,write(Z)) ).
?- 2 plus 4.
6
Yes
Example 10:
?op(11,yf,'*'). ?op(11,yf,'+').
?- I is *(4 ,
+(3,3)). I = 24
Yes

Example 11:
:
:

- op ( 2 5,x f ,[ m in ute s ] ) .
- ar it hm eti c _ fu n ct i on ( mi nu t es/ 1 ) .
m i nu t es ( M ,S ) : - S i s M * 6 0 .
E x a mpl e1 2:
? - T i m e is 3 mi n ut e s .
T i m e = 18 0
yes
STRINGIZING AND TOKEN PASTING:
Token:
Token is the smallest unit in a program which cant be broken up more into its components by the
program.
#

include<stdio.h
> #define
VAR(i,j) (i##j)
define paster(n) printf("token" #n "= %d", token##n)

void main(void)
{
int z1=2;
int a =VAR(z,1);
int tokeni=3;
paster(i);

( = . . ' uni v' ) cross converts for term and list .


?- P =.. [a,b,c].
P = a(b, c)
Yes
?[a,b,c]
=.. P. P
= ['.', a,
[b, c]]
Yes
?- a(b, c) =..P. ------Making tokens from
predicates
P = [a, b, c]
Yes
?
X
i
s
h
i
(
2
)
,
[
X
,
a
]
=
.
.
S
.
1
2
0
X = 120
S = ['.', 120, [a]]
Yes
?

------- Making predicates from tokens


------- list to list( categorizing predicate
name, arity list and period .)

p
a
r
e
n
t
(
a
,
X
)
=
.
.
L
.
L
=
[
p
a
r
e
n
t
,
a
,
_
X
0

0
1
]
?
P
=
.
.
[
p
a
r
e
n
t
,
j
a
c
k
,
m
a
r
y
]
.
P
=
p
a
r
e
n
t
(
j
a
c
k
,
m
a
r
y

)
? - yes = .. L .
L = [ yes ]
?
P
=
.
.
[
f
a
c
t
]
.
P
=
f
a
c
t
MAKING PREDICATES USING TOKENS AND
SEPARATED TERMS
P
=
.
.
[
h
i
,
2
]
,
c
a
l

l
(
C
i
s
P
)
.
1
2
0
P
=
h
i
(
2
)
C
=
1
2
0
Y
e
s
Parsing a function :
: - arithmetic_function(hi /1) .
file
hi(A,C):-C is A*6 0, print(C).
parse( X , Y ) : - parse( X , Y , _ ) .
parse( X , Y, A ) : - Z= . . [ X, Y , A] , call(Z) .
? - parse( hi ,2 ) .
1 2 0 query

d e f i ni ti o n

in . p l

Y es
? - A =2,B=3,[A,B]=..C,C=[X|Y],Z=Y,M = . .[Y],Y=[N|O],
write(N),w r i t e ( O ) .

US I NG Q UOTE S ( O R )
? - w rit e ( "S e co nd s") .
[ 32 , 8 3 , 1 01 , 9 9 , 1 1 1 , 1 10 , 1 0 0,
115 ] yes
? - w rit e ( S ec on
ds ) . S eco nd s
Yes
Arithmetic Comparison Operators
The arithmetic comparison operators are :<=<>>==:=/=
X<Y
True if X is less than Y.
X=<Y
True if X is less than or equal to Y.
X>Y
True if X is greater than Y.
X>=
True if X is greater than or equal to Y.
X=:=Y
True if X is equal to Y.
X=/=Y
True if the values of X and Y are not equal unlike unification theses operators cannot be used to
give values to a variable. The can only be valuated when every term on each side have been
instantiated.
Term Comparison
comparison There is an order on the Prolog terms. The operators of comparison are
:@<@=<@>@>= X@<Y
The term X is less than Y
Y@=<Y
The term X is less than or equal to Y
X@>Y
The term X is greater than Y
X@>=Y
The term X is greater or equal to Y

The term order from the lowest to the highest is :


1. Variables.
2. Floating point numbers.
3. Integers.
4. Atoms in the alphabetical order.

S-ar putea să vă placă și