Home Previous Next

CSC240 :: Lecture Note :: Week 13
Assignments | Code | Handouts | Resources | Email Thurman {Twitter::@compufoo Facebook::CSzero}
{GDT::Bits:: Time  |  Weather  |  Populations  |  Special Dates}

Overview

Assignment(s):

Code: dot-pl directory listing


Hello, World (Fact, Rules, Queries)

Prolog in a nutshell: Facts, rules, queries. Facts and rules comprise a "knowledge base" that is then used as a "database" for queries.

I am using gprolog (GNU Prolog) to learn about Prolog.

| ?- is the gprolog prompt.

Statements end with a period (.) and % starts a comment that ends at the end of the line. Note: The period is called a full stop.

halt. is used to exit gprolog.

Prolog programs are stored in files that end in either dot-pl, dot-pro, or dot-P.

$ gprolog       # shell command-line

GNU Prolog 1.3.0
By Daniel Diaz
Copyright (C) 1999-2007 Daniel Diaz

| ?- write('hello, world'), nl, write('prolog--logic programming').
hello, world
prolog--logic programming

yes

| ?- halt.

$ edit mcccd.pl     # and type in a knowledge base
$ cat mcccd.pl

% here are some facts
mcccd('Maricopa County Community College District').
campus(scc).
campus(mcc).
campus(gcc).

$ gprolog

| ?- [mcccd].    % load knowledge base; could do: consult('mcccd.pl').

compiling /home/gdt/prolog/mcccd.pl for byte code...
/home/gdt/prolog/mcccd.pl compiled, 4 lines read - 576 bytes written, 7 ms

yes

| ?- campus(scc).

yes
| ?- campus(foo).

no

| ?- listing(mcccd).

mcccd('Maricopa County Community College District').

yes

| ?- listing(campus).

campus(scc).
campus(mcc).
campus(gcc).

yes

| ?- campus(X).

X = scc ? ;

X = mcc ? ;

X = gcc

yes

| ?- foo = foo.    % foo unifies with foo

yes

| ?- foo = goo.    % foo does not unify with goo

no

| ?- 3 > 5.        % numeric greater than

no

| ?- 5 > 3.

yes

| ?- 3 >= 5.       % numeric greater than or equal to

no

| ?- 3 <= 5.
uncaught exception: error(syntax_error('user_input:18 (char:3) . or operator expected after expression'),read_term/3)

| ?- 3 =< 5.       % numeric equal to or less than

yes


| ?- 3 \= 5.      % yes 3 and 5 do not unify

yes

| ?- 3 \= 3.

no


| ?- 5 =:= 3.

no


| ?- 5 =:= 5.

yes

| ?- 5 =\= 3.

yes


| ?- X is 1 + 1.

X = 2

yes

| ?- X is 5 / 2.

X = 2.5

yes

| ?- X is 5 / 0.
uncaught exception: error(evaluation_error(zero_divisor),(is)/2)


| ?- X is 1 + (2 * 3).

X = 7

yes

| ?- (3 * 5) > (3 + 5).

yes

| ?- (3 * 5) > (5 * 3).

no




| ?- 5 == X.

no
| ?- X is 2 + 3.

X = 5

yes

| ?- 5 =:= X.
uncaught exception: error(instantiation_error,(=:=)/2)

| ?- 5 = X.

X = 5

yes

| ?- random(1,5,X.
Prolog interruption (h for help) ? c
).
uncaught exception: error(syntax_error('user_input:30 (char:13) , or ) expected'),read_term/3)

| ?- random(1,5,X).

X = 4

yes

| ?- X is abs(-3).

X = 3

yes

| ?- X is min(5,10).

X = 5

yes

| ?- X is max(5,10).

X = 10

yes

| ?- 


| ?- X is abs(-3).

X = 3

yes

| ?- X is min(5,10).

X = 5

yes

| ?- X is max(5,10).

X = 10

yes

| ?- X is round(3.1416).

X = 3

yes

| ?- X is floor(3.1416).

X = 3

yes

| ?- X is truncated(3.1416).
uncaught exception: error(type_error(evaluable,truncated/1),(is)/2)

| ?- X is truncate(3.1416).

X = 3

yes

| ?- X is ceiling(3.1416).

X = 4

yes

| ?- X is 2^3.

X = 1

yes

| ?- X is 2**3.

X = 8.0

yes


| ?- atom(X).

no

| ?- atom(x).

yes

| ?- atom('x').

yes

| ?- atom("x").

no

| ?- atom(_x).

no

| ?- X is sqrt(25).

X = 5.0

| ?- X is sqrt(-1).

X = -nan


yes
| ?- X is 5 ** 2.

X = 25.0

yes

| ?- X is exp(1).

X = 2.7182818284590451

| ?- X is log(exp(1)).

X = 1.0

yes
Day 2...

About ^ in gprolog...

| ?- X is 2^3.

X = 1

yes

% hmm... ^ is not power (exponent)

| ?- X is 5^2.

X = 7

yes

| ?- X is 1^3.

X = 2

yes

% hmm... ^ appears to be bit-wise exclusive or... 
% but, let's consult the documentation...

% copy/paste from gprolog.org/manual
% "An arithmetic expression is a Prolog term built from numbers, 
%  variables, and functors (or operators) that represent arithmetic 
%  functions. When an expression is evaluated each variable must be 
%  bound to a non-variable expression. An expression evaluates to a 
%  number, which may be an integer or a floating point number. The 
%  following table details the components of an arithmetic expression, 
%  how they are evaluated, the types expected/returned and if they are 
%  ISO or an extension:" [long table presented]
%
%  expression  Result=eval(Expression)                  Signature      ISO
%  =======================================================================
%  xor(E1,E2)   eval(E1) bitwise_xor eval(E2)            I, I -> I       Y 
%  E1 ^ E2      eval(E1) raised to the power of eval(E2) IF, IF -> IF    Y 
%  E1 ** E2     eval(E1) raised to the power of eval(E2) IF, IF -> IF    Y 
%
%  goto('gprolog.org/manual/gprolog.html#sec98').

| ?- X is xor(5, 2).
uncaught exception: error(type_error(evaluable,xor/2),(is)/2)

% D'OH!

% resume...

| ?- X is 5 >> 1.

X = 2

yes
| ?- X is 5 << 1.

X = 10

yes

% lists...

| ?- [1,2,3,4] = [H|T].

H = 1
T = [2,3,4]

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

H = 1
T = []

yes

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

no

| ?- [foo, goo, moo] = [Car | Cddr].

Car = foo
Cddr = [goo,moo]

yes


ling /home/gdt/gdt/csc240/prolog/lisp.pl for byte code...
/home/gdt/gdt/csc240/prolog/lisp.pl:1: warning: singleton variables [T] for car/2
/home/gdt/gdt/csc240/prolog/lisp.pl:2: warning: singleton variables [H] for cdr/2
/home/gdt/gdt/csc240/prolog/lisp.pl compiled, 2 lines read - 488 bytes written, 6 ms

yes

| ?- car([1,2,3],X).

X = 1

yes

| ?- cdr([1,2,3],Y).

Y = [2,3]

yes

| ?- halt.

{TopOfPage} {Resources}


Prolog Interactions by Alain Colmerauer

Alain.Colmerauer.free.fr::From natural language processing to Prolog (Beijing, April 8, 2011)

   INPUT TEXT:
      KAYSER WORKS IN PARIS.
      EVERY PERSONNE WHO WORKS IN PARIS, TAKES THE UNDERGROUND.
      KAYSER IS A PERSON.
   query:
      WHAT DOES KAYSER TAKE?

   ANSWER:
      +SORT(THE UNDERGROUND) ;.

   INPUT TEXT:
      THE ICE IS A SOLID.
      EVERY SOLID WHICH MELTS, IS A LIQUID.
      KAYSER DRINKS ICE WHICH MELTS.

   query:
      WHO DRINKS A LIQUID?
      DOES KAYSER DRINKS A LIQUID?

   ANSWER:
      +SORT(KAYSER) ;.
      +SORT(YES) ;.

   INPUT TEXT:
      THE MONDE INFORMS EVERY FELLOW WHO READS IT.
      THE PRESIDENT IS A FELLOW.

   query:
      WHO READS THE MONDE?
      WHOM DOES INFORM THE MONDE?

   ANSWER:
      +SORT(THE PRESIDENT) ;.
      +SORT(THE PRESIDENT) ;.


The progam about brother and sister

   brothersister(X,Z) :- issonof(X,Y), isdaughterof(Z,Y).
   isdaughterof(helen,judith).
   isdaughterof(nicole,mary).
   isdaughterof(rachel,mary).
   issonof(jules,judith).
   issonof(paul,judith).
   issonof(robert,mary).

   First execution
   > brothersister(paul,X)?
   X=helen.

   Second execution
   > brothersister(X,helen)?
   X=jules.
   X=paul.

   First execution, details
   > brothersister(paul,X)?
      brothersister(X1,Z1) :- issonof(X1,Y1), isdaughterof(Z1,Y1).
      X1=paul, X=Z1
   > issonof(paul,Y1), isdaughterof(Z1,Y1)?
      issonof(paul,judith).
      Y1=judith.
   > isdaughterof(Z1,judith)?
      isdaughterof(helen,judith).
      Z1=helen
      X=helen

   Second execution, details
   > brothersister(X,helen)?
      brothersister(X1,Z1) :- issonof(X1,Y1), isdaughterof(Z1,Y1).
      X=X1, Z1=helen
   > issonof(X1,Y1), isdaughterof(helen,Y1)?
      issonof(jule,judith).
      X1=jule, Y1=judith
   > isdaughterof(helen,judith)?
      isdaughterof(helen,judith).
      X=jule
      issonof(paul,judith).
      X1=paul, Y1=judith
   > isdaughterof(helen,judith)?
      isdaughterof(helen,judith).
      X=paul
      issonof(robert,mary).
      X1=robert, Y1=mary
   > isdaughterof(helen,judith)?
      isdaughterof(helen,mary).

{TopOfPage} {Resources}


Brother and Sister

Entered Alain Colmerauer's brother and sister program into gprolog via a file named bs.pl.

| ?- [bs].
compiling /home/gdt/prolog/bs.pl for byte code...
/home/gdt/prolog/bs.pl compiled, 7 lines read - 1152 bytes written, 9 ms

yes
| ?- brothersister(jules, helen).

yes
| ?- brothersister(jules, nicole).

| ?- isdaughterof(helen,mary).

no
| ?- isdaughterof(helen,judith).

yes
| ?- isdaughterof(helen,Mom).   

Mom = judith

yes
| ?- isdaughterof(Kid,mary).

Kid = nicole ? ;

Kid = rachel

yes

| ?- brothersister(jules,helen).

yes
| ?- brothersister(paul,helen).

yes

| ?- brothersister(paul, Sister).

Sister = helen ? ;

no
| ?- brothersister(X, helen).

X = jules ? ;

X = paul ? ;

no

% added to bs.pl...
% ismom(ismom(X,Y) :- issonof(X,Y); isdaughterof(X,Y).

| ?- ismom(X, judith).

X = jules ? ;

X = paul ? ;

X = helen ? ;

no

{TopOfPage} {Resources}


DAI.ed.ac.uk::Unification

{TopOfPage} {Resources}


Read From Standard Input
3 ?- read(X).        % I typed in hello.
|: hello.

4 ?- var(X).
true.

5 ?- ground(X).
false.

6 ?- not(var(X)).
false.

7 ?- not(ground(X)).
true.

{TopOfPage} {Resources}


Backtracking

One key to Prolog's usefulness: "backtracking."

   0) find all possible solutions
   1) re-evaluate each possible solution
   2) abandons X (variable) if X is not the solution

Prolog uses a database that contains rules and facts (clauses). The rules help the program to "decide the logical approach and it checks against the facts (givens)."

{TopOfPage} {Resources}


%
% personal.pl is a knowledge base
%

retired(truman).
healthy(gerald).
wise(truman).
over65(truman).
wealthy(truman).
happy(X) :- wealthy(X), healthy(X), wise(X).
senior(X) :- retired(X); over65(X).


| ?- happy(truman).
no

| ?- happy(gerald).
no

| ?- over65(truman).
yes

| ?- over65(gerald).
no

| ?- listing(happy).
happy(A) :-
	wealthy(A),
	healthy(A),
	wise(A).
yes

| ?- listing(retired).
retired(truman).
yes

| ?- listing(healthy).
healthy(gerald).
yes

{TopOfPage} {Resources}


%
% coding.pl is a knowledge base
%

programmingLanguage(cpp).
programmingLanguage(lisp).
programmingLanguage(prolog).
programmingLanguage(java).
programmingLanguage(c).
programmingLanguage(X) :- course(X,240).
course(cpp, 240).
course(lisp, 240).
course(prolog, 240).
course(java, 205).
course(java, 110).
course(cpp, 100).

%
% | ?- course(X,240).
% X = cpp ? ;
% X = lisp ? ;
% X = prolog ? ;
% no
%
%
% | ?- programmingLanguage(cobol).
% no
%
% | ?- programmingLanguage(c).
% true ? ;
% no
%
% | ?- course(c, Y).
% no
% | ?- course(cpp, Y).
% Y = 240 ? ;
% Y = 100
% yes
%
% | ?- programmingLanguage(L).
% L = cpp ? ;
% L = lisp ? ;
% L = prolog ? ;
% L = java ? ;
% L = c ? ;
% L = this_is_a_test ? ;
% L = 'programming logic' ? ;
% L = cpp ? ;
% L = lisp ? ;
% L = prolog ? ;
% no
%


{TopOfPage} {Resources}


%
% creators.pl is a knowledge base
%
iscreatorof(dmr,c).
iscreatorof(att,c).
iscreatorof(bs,cpp).
iscreatorof(att,cpp).
iscreatorof(gosling,java).
iscreatorof(sunmicrosystems,java).
iscreatorof(mccarthy,lisp).
iscreatorof(colmerauer,prolog).
iscreatorof(roussel,prolog).
iscreatorof(sh,bourne).
iscreatorof(att,bourne).
iscreatorof(perl,wall).
iscreatorof(gcc,stallman).
iscreatorof(kernighan,awk).
iscreatorof(aho,awk).
iscreatorof(weinberg,awk).
iscreatorof(att,awk).
iscreatorof(backus,fortran).
% create years are approximate
createdin(c, 1972).
createdin(cpp, 1982).
createdin(prolog, 1972).
createdin(java, 1991).
createdin(fortran, 1957).

% | ?- iscreatorof(X, awk).
% X = kernighan ? ;
% X = aho ? ;
% X = weinberg ? ;
% X = att ? ;
% no

% | ?- iscreatorof(att, X).
% X = c ? ;
% X = cpp ? ;
% X = bourne ? ;
% X = awk
% yes

{TopOfPage} {Resources}


%
% colors.pl is a knowledge base
%
rgb(red).
rgb(green).
rgb(blue).

cymk(cyan).
cymk(yellow).
cymk(magenta).
cymk(black).

color(pink).
color(yellow).
color(magenta).
color(cyan).
color(pink).
color(red).
color(green).
color(blue).
color(white).

isprimarycolor(X) :- rgb(X).
issecondarycolor(X) :- cymk(X).

%
% testing the knowledge base
% 

% | ?- isprimarycolor(pink).
% no

% | ?- isprimarycolor(red).
% yes

% | ?- issecondarycolor(pink).
% no

% | ?- issecondarycolor(yellow).
% yes

% | ?- isprimarycolor(X).
% X = red ? ;
% X = green ? ;
% X = blue
% yes

% | ?- issecondarycolor(X).
% X = cyan ? ;
% X = yellow ? ;
% X = magenta ? ;
% X = black
% yes

{TopOfPage} {Resources}


Unification

Three types of terms: constants (atoms, numbers); variables; complex terms... functor(term1,term2,...)

Athena.ecs.csus.edu:: "Unification leads to Instantiation".

Unification I: If term1 and term2 are constants, then they unify if and only if same atom or same number.

[0] ?- 240 = 240.
yes

[1] ?- 240 = 420.
no

[2] ?- prolog = prolog.
yes

[3] ?- prolog = lisp.
no

[4] ?- 'prolog' = prolog.
yes

[5] ?- prolog = 'prolog'.
yes

[6] ?- 240 = '240'.
no

[7] ?- =(c, cpp).
no

[8] ?- =(240, 240).
yes

[9] ?- =(240, 420).
no

Unification II: "If term1 is a variable and term2 is any type of term, then term1 and term2 unify, and term1 is instantiated to term2. Similarly, if term2 is variable and term1 is any type of term, then term 1 and term2 unify, and term2 is instantiated with term1. (So if they are both variables, they're both instantiated to each otehr, and we say that they share values.)" -- LearnPrologNow.org

[10] ?- X = foo.
X = foo
yes

[11] ?- foo = X.
X = foo
yes

[12] ?- X = 240.
X = 240
yes

[13] ?- '240' = X.
X = '240'
yes

[14] ?- X = Y.
Y = X
yes

[15] ?- X = c, X = lisp.
no

[16] ?- lang(c) = lang(c).
yes

[17] ?- lang(c) = lang(lisp).
no

Unification III: "If term1 and term2 are complex terms, then they unify if an only if: 1. They have the same functor and arity, and 2. all their corresponding arguments unify, and 3. the variable instantiations are compatible." -- LearnPrologNow.org section 2.1

[18] ?- foo(goo) = foo(goo).    % foo functors match, goo arguments match
yes

[19] ?- foo(goo) = foo(boo).    % functors match, but arguments don't
no

[19] ?- f(g(X)) = f(g(Y)).      % functors f match; functors g match
Y = X                          
yes

[20] ?- f(g(x)) = g(f(x)).      % f and g are not the same functor
no

[21] ?- =(lang(X), lang(Y)).    % recall there's infix notation
Y = X
yes
DOC.gold.ac.uk::Exercises

{TopOfPage} {Resources}


LearnPrologNow.org Line Program...
dot-pl file:

vertical(line(point(X, Y), point(X, Z))).
horizontal(line(point(X, Y), point(Z, Y))).

verticalline(point(X, Y), point(X, Z)).
horizontalline(point(X, Y), point(Z, Y)).


| ?- listing.
verticalline(point(A, _), point(A, _)).
horizontalline(point(_, A), point(_, A)).

| ?- verticalline(point(1,4),point(1,7)).
yes

| ?- verticalline(point(1,4),point(2,4)).
no

| ?- horizontalline(point(1,2),point(2,2)).
yes

| ?- horizontalline(point(1,2),point(2,3)).
no

{TopOfPage} {Resources}


Home Previous Next