Ekspertni Prolog Language 184
Ekspertni Prolog Language 184
Ekspertni Prolog Language 184
1
(ISO-)Prolog
2
Programming interface (writing and running programs)
3
Our Development Environment: The Ciao System
• We use the (ISO-Prolog subset of the) Ciao multiparadigm programming system.
• In particular, the Ciao system offers both command line and graphical
environments for editing, compiling, debugging verifying, optimizing, and
documenting programs, including:
A traditional, command line interactive top level.
A stand-alone compiler (ciaoc).
Compilation of standalone executables, which can be:
* eager dynamic load
* lazy dynamic load
* static (without the engine –architecture independent)
* fully static/standalone (architecture dependent)
Prolog scripts (architecture independent).
Source debugger, embeddable debugger, error location, ...
Auto-documenter.
Compile-time checking of assertions (types, modes, determinacy, non-failure,
etc. ...) and static debugging, etc.!
4
• Reading the first slides of the Ciao tutorial regarding the use of the
compiler, top-level, debuggers, environment, module system, etc. is
suggested at this point.
• Also, reading the corresponding parts of the Ciao manual.
5
Prolog Syntax and Terminology
6
Prolog Syntax — Operators
• Certain functors and predicate symbols are pre–defined as infix, prefix, or postfix
operators, aside from the standard term notation.
• Very useful to make programs (or data files) more readable.
• Stated using operator declarations:
:- op(<precedence>, <type>, <operator(s)>). where:
<precedence>: integer from 1 to 1200.
E.g., if ‘+’ has higher precedence than ‘/’, then
a+b/c ≡ a+(b/c) ≡ +(a,/(b,c)).
Otherwise, use parenthesis: /(+(a,b),c) ≡ (a+b)/c
<type>:
* infix: xfx (not associative), xfy (right associative), yfx (left associative).
* prefix: fx (non-associative), fy (associative).
* postfix: xf (non-associative), yf (associative).
<operator(s)>: can be a single atom or a list of atoms.
7
Prolog Syntax — Operators (Contd.)
• Examples:
Standard Notation Operator Notation
’+’(a,’/’(b,c)) a+b/c
is(X, mod(34, 7)) X is 34 mod 7
’<’(’+’(3,4),8) 3+4 < 8
’=’(X,f(Y)) X = f(Y)
’-’(3) -3
spy(’/’(foo,3)) spy foo/3
’:-’(p(X),q(Y)) p(X) :- q(Y)
’:-’(p(X),’,’(q(Y),r(Z))) p(X) :- q(Y),r(Z)
• Note that, with this syntax convention, Prolog clauses are also Prolog terms!
• Parenthesis must always be used for operators with higher priority than 1000
(i.e., the priority of ’,’): ..., assert( (p :- q) ), ...
• Operators are local to modules (explained later).
8
Prolog Syntax — Operators (Contd.)
9
The Execution Mechanism of Prolog
• Always execute literals in the body of clauses left-to-right.
• At a choice point, take first unifying clause (i.e., the leftmost unexplored branch).
• On failure, backtrack to the next unexplored clause of last choice point.
grandparent(C,G):- parent(C,P), parent(P,G).
grandparent(charles,X)
10
Comparison with Conventional Languages
11
Control of Search in Prolog
12
Control of Search in Prolog (Contd.)
13
Programmer Interface: The Classical Top-Level Shell
• Modern Prolog compilers offer several ways of writing, compiling, and running
programs.
• Classical model:
User interacts directly with top level (includes compiler/interpreter).
A prototypical session with a classical Prolog-style, text-
based, top-level shell (details are those of the Ciao system, user input in bold):
[37]> ciao Invoke the system
Ciao 1.11 #211: Thu Mar 18 15:28:12 CET 2004
?- use module(file). Load your program file
yes
?- query containing variable X. Query the program
X = binding for X ; See one answer, ask for another using “;”
X = another binding for X <enter> Discard rest of answers using <enter>
?- another query. Submit another query
?- .......
?- halt. End the session, also with ˆ D
14
Traditional (“Edinburgh”) Program Load
15
Ciao Program Load
16
Top Level Interaction Example
• File member.pl:
:- module(member,[member/2]).
member(X, [X|_Rest]).
member(X, [_Y|Rest]):- member(X, Rest).
?- use_module(member).
yes
?- member(c,[a,b,c]).
yes
?- member(d,[a,b,c]).
no
?- member(X,[a,b,c]).
X = a ? ;
X = b ? (intro)
yes
17
Tracing an Execution with The “Byrd Box Model”
• Procedures (predicates) seen as “black boxes” in the usual way.
• However, simple call/return not enough, due to backtracking.
• Instead, “4-port box view” of predicates:
Call Exit
member(X,[X|Ys]).
Fail member(X,[Y|Ys]):- member(X,Ys). Redo
yes
?- debug_module(member).
{Consider reloading module member}
{Modules selected for debugging: [member]}
{No module is selected for source debugging}
yes
?- trace.
{The debugger will first creep -- showing everything (trace)}
yes
{trace}
?-
19
Debugging Example (Contd.)
?- lmember(X,[a,b]).
1 1 Call: member:lmember(_282,[a,b]) ?
1 1 Exit: member:lmember(a,[a,b]) ?
X = a ? ;
1 1 Redo: member:lmember(a,[a,b]) ?
2 2 Call: member:lmember(_282,[b]) ?
2 2 Exit: member:lmember(b,[b]) ?
1 1 Exit: member:lmember(b,[a,b]) ?
X = b ? ;
1 1 Redo: member:lmember(b,[a,b]) ?
2 2 Redo: member:lmember(b,[b]) ?
3 3 Call: member:lmember(_282,[]) ?
3 3 Fail: member:lmember(_282,[]) ?
2 2 Fail: member:lmember(_282,[b]) ?
1 1 Fail: member:lmember(_282,[a,b]) ?
no
20
Options During Tracing
21
Spypoints (and breakpoints)
• ?- spy foo/3.
Place a spypoint on predicate foo of arity 3 – always trace events involving this
predicate.
• ?- nospy foo/3.
Remove the spypoint in foo/3.
• ?- nospyall.
Remove all spypoints.
• In many systems (e.g., Ciao) also breakpoints can be set at particular program
points within the graphical environment.
22
Debugger Modes
• ?- debug.
Turns debugger on. It will first leap, stopping at spypoints and breakpoints.
• ?- nodebug.
Turns debugger off.
• trace.
The debugger will first creep, as if at a spypoint.
• notrace.
The debugger will leap, stopping at spypoints and breakpoints.
23
Built-in Arithmetic
24
Built-in Arithmetic (Contd.)
25
Arithmetic Programs
• plus(X,Y,Z) :- Z is X + Y
Only works in one direction (X and Y bound to arithmetic terms).
Meta-logical tests (see later) allow using it in both directions.
We have lost the recursive structure of the numbers.
But we have won (a lot) in performance!
• Factorial:
Using Prolog arithmetic:
Using Peano arithmetic:
factorial(0,1).
factorial(0,s(0)). factorial(N,F):-
factorial(s(N),F):- N > 0,
factorial(N,F1), N1 is N-1,
times(s(N),F1,F). factorial(N1,F1),
F is F1*N.
• Wrong goal order can raise an error (e.g., moving last call to is/2 before call to
factorial).
26
Type Checking Predicates
27
Type Checking Predicates (Contd.)
plus(X,Y,Z):- number(X),number(Y), Z is X + Y.
plus(X,Y,Z):- number(X),number(Z), Y is Z - X.
plus(X,Y,Z):- number(Y),number(Z), X is Z - Y.
Then:
?- plus(3,Y,5).
Y = 2 ?
?- plus(X,Y,5).
no
(in fact, this should raise an error, rather than simply failing).
28
Structure Inspection
• functor(X, F, A):
X is a compound term f(X1,...,Xn)→ F=f A = n
F is the atom f and A is the integer n → X = f(X1,..,Xn)
Error if X, and either F or A are variables
Fails if the unification fails, A is not an integer, or F is not an atom
Examples:
functor(t(b,a),F,A) → F=t, A=2.
functor(Term,f,3) → Term = f( , , ).
functor(Vector,v,100) → Vector = v( , ... , ).
(Note: in some systems functor arity is limited to 256)
29
Structure Inspection (Contd.)
• arg(N, X, Arg):
N integer, X compound term → Arg unified with n-th argument of X.
Allows accessing a structure argument in constant time and in a compact way.
Error if N is not an integer, or if X is a free variable.
Fails if the unification fails.
Examples:
?- _T=date(9,February,1947), arg(3,_T,X).
X = 1947
?- _T=date(9,February,1947), _T=date(_,_,X).
X = 1947
?- functor(Array,array,5),
arg(1,Array,black),
arg(5,Array,white).
Array = array(black,_,_,_,white).
• What does ?- arg(2,[a,b,c,d],X). return?
30
Example of Structure Inspection
subterm(Term,Term).
subterm(Sub,Term):-
functor(Term,F,N),
subterm(N,Sub,Term).
subterm(N,Sub,Term):-
arg(N,Term,Arg), % also checks N > 0 (arg/1 fails otherwise!)
subterm(Sub,Arg).
subterm(N,Sub,Term):-
N>1,
N1 is N-1,
subterm(N1,Sub,Term).
31
Example of Structure Access
32
Higher-Order Structure Inspection
33
Conversion Between Strings and Atoms
34
Meta-Logical Predicates
35
Meta-Logical Predicates (Contd.)
• Example:
length(Xs,N):-
var(Xs), integer(N), length_num(N,Xs).
length(Xs,N):-
nonvar(Xs), length_list(Xs,N).
length_num(0,[]).
length_num(N,[_|Xs]):-
N > 0, N1 is N - 1, length_num(N1,Xs).
length_list([],0).
length_list([X|Xs],N):-
length_list(Xs,N1), N is N1 + 1.
• But note that it is not really needed: the normal definition of length is actually
reversible!
36
Comparing Non-ground Terms
37
Comparing Non-ground Terms (Contd.)
38
Input/Output
39
Input/Output (Contd.)
40
Input/Output (Contd.)
• Example:
write_list_to_file(L,F) :-
telling(OldOutput), % Grab current output stream.
tell(F), write_list(L), told, % Write into F, close.
tell(OldOutput). % Reset previous output stream.
write_list([]).
write_list([X|Xs]):- write(X), nl, write_list(Xs).
• More powerful and format-based input-output predicates are available (see, e.g.,
format/2 and format/3 –Prolog system manuals).
• All these input-output predicates are “side-effects”!
41
Pruning Operator: Cut
• A “cut” (predicate !/0) commits Prolog to all the choices made since the parent
goal was unified with the head of the clause in which the cut appears.
• Thus, it prunes:
all clauses below the clause in which the cut appears, and
all alternative solutions to the goals in the clause to the left of the cut.
But it does not affect the search in the goals to the right of the cut.
s(a). p(X,Y):- l(X). r(a).
s(b). p(X,Y):- r(X), !, ... r(b).
p(X,Y):- m(X), ...
with query ?- s(A),p(B,C).
If execution reaches the cut (!):
The second alternative of r/1 is not considered.
The third clause of p/2 is not considered.
42
Pruning Operator: Cut (Contd.)
| ?- s(A), p(B,C).
A/a A/b
p(B,C) p(B,C)
43
“Types” of Cut
max(X,Y,X):- X > Y, !.
max(X,Y,Y):- X =< Y.
address(X,Add):- home_address(X,Add), !.
address(X,Add):- business_address(X,Add).
membercheck(X,[X|Xs]):- !.
membercheck(X,[Y|Xs]):- membercheck(X,Xs).
44
“Types” of Cut (Contd.)
• Red cuts: discard solutions which are not correct according to the intended
meaning.
Example:
max(X,Y,X):- X > Y,!.
max(X,Y,Y).
wrong answers to, e.g., ?- max(5, 2, 2).
Example:
days_in_year(X,366):- leap_year(X),!.
days_in_year(X,365).
wrong answers to, e.g., ?- days in year(a, D).
Red cuts affect completeness and one can no longer rely on the strict declarative
interpretation of the program for reasoning about correctness – avoid when
possible.
45
Meta–calls and Implementing Higher Order
• The meta-call call(X) converts a term X into a goal and calls it.
• When called, X must be instantiated to a term, otherwise an error is reported.
• Used for meta-programming, specially interpreters and shells.
Also for defining negation (as we will see) and implementing higher order.
• Example:
• Example:
46
Meta–calls – Aggregation Predicates
47
Meta–calls – Aggregation Predicates (Contd.)
48
Meta-calls – Aggregation Predicates: Examples
49
Meta-calls – Negation as Failure
• Uses the meta-call facilities, the cut and a system predicate fail that fails when
executed (similar to calling a=b).
50
Cut-Fail
52
Dynamic Program Modification (II)
• Example program:
relate_numbers(X, Y):- assert(related(X, Y)).
unrelate_numbers(X, Y):- retract(related(X, Y)).
• Example query:
?- related(1, 2).
{EXISTENCE ERROR: ...}
?- relate_numbers(1, 2).
yes
?- related(1, 2).
yes
?- unrelate_numbers(1, 2).
yes
?- related(1, 2).
no
• Rules can be asserted dynamically as well.
53
Dynamic Program Modification (III)
• Example program:
fib(0, 0). lfib(N, F):- lemma_fib(N, F), !.
fib(1, 1). lfib(N, F):-
fib(N, F):- N > 1,
N > 1, N1 is N - 1,
N1 is N - 1, N2 is N1 - 1,
N2 is N1 - 1, lfib(N1, F1),
fib(N1, F1), lfib(N2, F2),
fib(N2, F2), F is F1 + F2,
F is F1 + F2. assert(lemma_fib(N, F)).
:- dynamic lemma_fib/2.
lemma_fib(0, 0). lemma_fib(1, 1).
• Compare fib(24,N) versus lfib(24,N)
54
Meta-Interpreters
• clause(head,body):
Reads a clause head :- body from the program.
For facts body is true.
• To use clause/2 a predicate must be declared dynamic.
• Simple (“vanilla”) meta-interpreter:
solve(true).
solve((A,B)) :- solve(A), solve(B).
solve(A) :- clause(A,B), solve(B).
55
Incomplete Data Structures
56
Standard qsort (using append)
qsort([],[]).
qsort([X|L],R) :-
partition(L,X,L1,L2),
qsort(L2,R2),
qsort(L1,R1),
append(R1,[X|R2],R).
partition([],_B,[],[]).
partition([E|R],C,[E|Left1],Right):-
E < C,
partition(R,C,Left1,Right).
partition([E|R],C,Left,[E|Right1]):-
E >= C,
partition(R,C,Left,Right1).
57
qsort w/Difference Lists (no append!)
dlqsort_([],R,R).
dlqsort_([X|L],R,R1) :-
partition(L,X,L1,L2),
dlqsort_(L1,R,[X|R0]),
dlqsort_(L2,R0,R1).
58
Parsing (using append and traditional lists)
%% ?- myphrase([t,h,e,’ ’,p,l,a,n,e,’ ’,f,l,i,e,s]).
myphrase(X) :-
append(A,T1,X), article(A), append(SP,T2,T1), spaces(SP),
append(N,T3,T2), noun(N), append(SPN,V,T3), spaces(SPN), verb(V).
article([a]).
article([t,h,e]).
spaces([’ ’]).
spaces([’ ’ | Y]) :- spaces(Y).
noun([c,a,r]).
noun([p,l,a,n,e]).
verb([f,l,i,e,s]).
verb([d,r,i,v,e,s]).
59
Parsing (using standard clauses and difference lists)
%% ?- myphrase([t,h,e,’ ’,p,l,a,n,e,’ ’,f,l,i,e,s],[]).
myphrase(X,CV) :-
article(X,CA), spaces(CA,CS1), noun(CS1,CN),
spaces(CN,CS2), verb(CS2,CV).
article([t,h,e|X],X).
article([a|X],X).
spaces([’ ’ | X],X).
spaces([’ ’ | Y],X) :- spaces(Y,X).
noun([p,l,a,n,e | X],X).
noun([c,a,r | X],X).
verb([f,l,i,e,s | X],X).
verb([d,r,i,v,e,s | X],X).
60
Parsing (same, using some string syntax)
%% ?- myphrase("the plane flies",[]).
myphrase(X,CV) :-
article(X,CA), spaces(CA,CS1), noun(CS1,CN),
spaces(CN,CS2), verb(CS2,CV).
61
Parsing (same, using additional syntax: DCGs)
:- use_package(dcg).
62
Parsing + actions (calling Prolog in DCGs)
:- use_package(dcg).
63
Creating Executables
64
Other issues in Prolog (see “The Art of Prolog” and Bibliography)
• Repeat loops.
• Exception handling.
• Extending the syntax beyond operators: term expansions/macros.
• Delay declarations/concurrency.
• Operating system interface (and sockets, etc.).
• Foreign language (e.g., C) interfaces.
• Many other built-ins...
• ...
65
Some Typical Libraries in Prolog Systems
66
Some Additional Libraries and Extensions (Ciao)
Other systems may offer additional extensions. Some examples from Ciao:
• Other execution rules:
Breadth-first execution
Iterative-deepening execution
Fuzzy Prolog, MYCIN rules, ...
Andorra (“determinate-first”) execution
• Interfaces to other languages and systems:
C, Java, ... interfaces
Persistent predicates and SQL database interface
Web/HTML/XML/CGI programming (PiLLoW) / HTTP connectivity
Interface to VRML (ProVRML)
Tcl/Tk interface
daVinci interface
Calling emacs from Prolog, etc.
67
Some Additional Libraries and Extensions (Ciao, Contd.)
68
Some Additional Libraries and Extensions (Ciao, Contd.)
69