1 history automatic theorem proving robinson 1965 “programming in logic” kowalski, 1974...

50
1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog, 1977 “Prolog 10”, David Warren Warren Abstract Machine Clocksin&Mellish, 1981

Upload: jeffry-armstrong

Post on 15-Jan-2016

217 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

1

History

Automatic Theorem Proving Robinson 1965

“PROgramming in LOGic” Kowalski, 1974 Deduction as computation

“Prolog”, Colmerauer, 1973

Edinburgh Prolog, 1977 “Prolog 10”, David Warren Warren Abstract Machine

Clocksin&Mellish, 1981

Page 2: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

2

What kind of a thing is Prolog?

Very different from C, C++, Java, and other Procedural languages

Symbolic Programming Language

Logic Programming Language

Declarative Programming Language

Page 3: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

3

Prolog program

A Prolog program is defined by a set of Predicates

Each Predicate has a unique Functor and Arityparent(Parent, Child)

a predicate whose functor is “parent” with arity 2.

Each Predicate is defined by a sequence of Clauses

A Clause is either a Fact or a Rule

fact(…).

head(…) :- goal1(…), … , goalN(…).

Each argument to a predicate is a Term

A Term is either: Atomic, Variable, or Compound

Page 4: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

4

Atomic terms

Atomic terms can be either atoms or numbers

Atoms can be a sequence of alphanumeric (including ‘_’) characters starting with a lower case letter, or a sequence of any characters embedded in single quote marks:johnDowding symbsys139p ‘quoted atom’ non_quoted_atom

Numbers can be integers or floating point

Page 5: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

5

Variables

Variables start with a capital letter or _ character X Parent _Sibling _

Variables can stand in for arbitrary Prolog terms (including other variables)

Variables that occur with the same name in the same clause represent the same variable, except for

The anonymous variable “_”, which always represents a unique variable.

Page 6: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

6

Compound Terms

A compound term is a structure with a functor and N arguments.

functor(Arg1, Arg2, …, ArgN)

Each argument can be an arbitrary Prolog term

Page 7: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

7

Example: Successor Arithmetic

Simple arithmetic using compound terms to represent integers:0 0

1 s(0)

2 s(s(0))

3 s(s(s(0)))

4 s(s(s(s(0))))

.

.

.

Page 8: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

8

Structural Induction and Recursion

Inductive proofs have a base (or terminating) case and an inductive step.

Mathematical induction – over the space of integers

Structural induction – over subsets of the space of Prolog Terms.

Many Prolog predicates have this structure:is_number(0).

is_number(s(Number)) :- is_number(Number).

Page 9: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

9

BUILT-IN Predicate: consult/1

consult(FileName)

Load the Prolog program in FileName into memory.

Page 10: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

10

Factorial

factorial(+N, ?Factorial) fact(1) = 1 fact(N+1)= (N+1) * fact(N)

%factorial(+Number, ?Factorial)

factorial(s(0), s(0)).

factorial(s(Number), Factorial):-

factorial(Number, PartialFactorial),

mult(s(Number), PartialFactorial, Factorial).

Page 11: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

11

Prolog Execution Model/Prolog Debugger

CALL EXIT

FAIL REDOparent(james, john).parent(james, alan).parent(florence, john).parent(florence, alan).parent(alan, elizabeth).parent(alan, emily).

Goal = parent(P, john) parent(james, john)parent(florence, john)

Page 12: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

12

Execution Model (conjunctions)

parent(james, john).parent(james, alan).parent(florence, john).parent(florence, alan).parent(alan, elizabeth).parent(alan, emily).

female(emily).female(florence).female(elizabeth).

parent(Mother, john) female(Mother)parent(james, john) female(james)parent(florence, john) female(florence)

Page 13: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

13

Execution Model – mult(s(s(s(0))), s(s(0)), Result)

mult(0, Term, 0):- is_number(Term).mult(s(Term1), Term2, Product):- mult(Term1, Term2, Partial), add(Term2, Partial, Product).

add(0, Sum, Sum):- is_number(Sum).add(s(Addend1), Addend2, s(Sum)):- add(Addend1, Addend2, Sum).

mult(s(s(0)),s(s(0)), Prod)

mult(s(0), s(s(0)), Partial) add(s(s(0)), Partial, Prod)

add(s(s(0)), Prod, Result)

mult(0, Term, 0):- is_number(Term).mult(s(Term1), Term2, Product):- mult(Term1, Term2, Partial), add(Term2, Partial, Product).

Page 14: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

14

Prolog Debugger Demo

Built-In predicates: trace/0. notrace/0.

Debugger actions: ‘c’ or <cr> - creep ‘s’ – skip ‘l’ – leap ‘r’ – retry ‘f’ – fail ‘a’ - abort

Page 15: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

15

And-Or Trees

or

andand and

ororor

ororor or

andandandandand and and

orororor

oror

or

Page 16: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

16

And-Or Tree (cont.)

or

and and

mult(0, Term, 0):- is_number(Term).

mult(s(Term1), Term2, Product):- mult(Term1, Term2, Partial), add(Term2, Partial, Product).

or or or

is_number(Term)mult(Term1, Term2, Partial)

add(Term2,Partial,Product)

and and and and and and

Page 17: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

17

Linked Lists

Prolog allows a special syntax for lists: [a,b,c] is a list of 3 elements [] is a special atom indicating a list with 0 elements

Internally, Prolog lists are regular Prolog terms with the functor ‘.’ (so called “dotted pairs”)[a,b,c] = ‘.’(a, ‘.’(b, ‘.’(c, []))).The symbol | in a list indicates “rest of list”, or the term that is the 2nd argument of a dotted pair.[a,b,c] = [a|[b,c]].[Head|Tail] is a common expression for dividing a list into its first element (Head) and the rest of the list (Tail).

Page 18: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

18

Example: list/1

% list(?List)

list([]).

list([_Head|Tail]):-

list(Tail).

Since Prolog is untyped, we don’t have to know anything about Head except that it is a term.

Page 19: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

19

Example: member/2

% member(?Element, ?List)

member(Element, [Element|_Tail]).

member(Element, [_Head|Tail]):-

member(Element, Tail).

Page 20: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

20

Example: delete/3

% delete(+Element, +List, -NewList)

% delete/3 succeeds if NewList results from removing

% one occurrence of Element from List.

delete(Element, [Element|Tail], Tail).

delete(Element, [Head|Tail], [Head|NewTail]):-

delete(Element, Tail, NewTail).

Page 21: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

21

Example: append/3

% append(?List1, ?List2, ?List3)

% append/3 succeds if List3 contains all the elements of

% List1, followed by all the elements of List2.

append([], List2, List2).

append([Head|List1], List2, [Head|List3]):-

append(List1, List2, List3).

Page 22: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

22

Example: “naïve” reverse

% "naive reverse": nreverse(?List, ?ReversedList).

nreverse([], []).

nreverse([Head|Tail], ReversedList):-

nreverse(Tail, ReversedTail),

append(ReversedTail, [Head], ReversedList).

Page 23: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

23

“Pure Prolog” and non-logical built-ins

All the examples so far have been “pure Prolog” Contain no built-ins with non-logical side-effects

Prolog has many built-in predicates: Type checking of terms Arithmetic Control execution Input and output Modify the program during execution Perform aggregation operations

Use of non-logical built-in predicates usually effects the reversability of your program.

Page 24: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

24

Type-checking Built-in Predicates

var(X) – is true when X is an uninstantiated variable.

nonvar(X) – is true when X is not a variable.

atom(X) – is true when X is a symbolic constant.

number(X) – is true when X is a number

atomic(X) – is true when atom(X) or number(X).

compound(X) – is true when X is a compound term.

Page 25: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

25

Term constructor/selectors: functor/3, arg/3

functor(+Term, ?Functor, ?Arity) Find the Functor and Arity of Term

functor(?Term, +Functor, +Arity) Constructs a new Term with Functor and Arity

arg(+N, +Term, ?SubTerm) Unifies SubTerm with the Nth argument of Term

Page 26: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

26

Arithmetic: Built-In is/2

Arithmetic expressions are not normally evaluated in Prolog.Built-In infix operator is/2 evaluates it’s 2nd argument, and unifies the result with it’s 1st argument.| ?- X = 5 + 2.X = 5+2?yes| ?- X is 5 + 2.X = 7 ?yes

Any variables in the right-hand side of is/2 must be instantiated when it is evaluated.

Revisit operator and arithmetic at a later time

Page 27: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

27

Cut (!)

The ! Symbol (pronounced “cut”) modifies the execution of your program by committing to certain choices. That is, it removes choice points.

Easy to describe what it does, more difficult to get used to using it properly.

Page 28: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

28

Cut (cont.)

Head1 :- Goal1, Goal2, …, GoalN, !, …Head2 :- …Head3 :- ……HeadN :- …

Removes the choice point that allows Head2 …HeadNRemoves any choice points that may have been introduced in Goal1 … GoalN.We will discuss Cut in more detail later on.

Page 29: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

29

Example: delete_first/3

% delete_first(+Element, +List, -NewList)

% removes the 1st occurrence of Element in List.

delete(Element, [Element|Tail], Tail):-

!.

delete(Element, [Head|Tail], [Head|NewTail]):-

delete(Element, Tail, NewTail).

Page 30: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

30

Built-Ins: Term Comparison Operators

Unifies with Term1 = Term2 iff unifies Term1 and Term2 if they are unifiable

Does not unify with Term1 \= Term2, Term1 and Term2 are unchanged

Identical Term1 == Term2 iff are the same terms

Not identical Term1 \== Term2

Page 31: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

31

Built-ins: true/0 and fail/0.

true. Always succeeds.

fail. Always fails.

Page 32: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

32

Meta-Predicates: call/1, \+/1

Meta-predicates take a Goal as an argument, and execute it.

call/1 executes it’s one argument.

\+(Goal) succeeds if call(Goal) fails.

\+/1 could also be defined using cut and fail.

\+(Goal) :- call(Goal), !, fail.

\+(_Goal).

Page 33: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

33

More about cut!

Common to distinguish between red cuts and green cuts Red cuts change the solutions of a predicate Green cuts do not change the solutions, but effect the efficiency

Most of the cuts we have used so far are all red cuts

%delete_all(+Element, +List, -NewList)delete_all(_Element, [], []).delete_all(Element, [Element|List], NewList) :- !, delete_all(Element, List, NewList).delete_all(Element, [Head|List], [Head|NewList]) :- delete_all(Element, List, NewList).

Page 34: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

34

Green cuts

Green cuts can be used to avoid unproductive backtracking% identical(?Term1, ?Term2)identical(Var1, Var2):-

var(Var1), var(Var2),!, Var1 == Var2.

identical(Atomic1,Atomic2):- atomic(Atomic1), atomic(Atomic2),!, Atomic1 == Atomic2.

identical(Term1, Term2):-compound(Term1),compound(Term2),functor(Term1, Functor, Arity),functor(Term2, Functor, Arity),identical_helper(Arity, Term1, Term2).

Page 35: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

35

Advice on cuts

Dangerous, easy to misuse

Rules of thumb: Use sparingly Use with as narrow scope as possible

Page 36: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

36

intersect/3

%intersect(+Set1, +Set2, ?Intersection)

intersect([], _Set2, []).

intersect([Element|RestSet1], Set2, [Element|Intersection]):-

member(Element, Set2),

!,

intersect(RestSet1, Set2, Intersection).

intersect([_Element|RestSet1], Set2, Intersection):-

intersect(RestSet1, Set2, Intersection).

Page 37: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

37

Example: Input/Output

repeat/0 is a built-in predicate that will always resucceed

% classifing terms

classify_term :-

repeat,

write('What term should I classify? '),

nl,

read(Term),

process_term(Term),

Term == end_of_file.

Page 38: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

38

I/O Example (cont)

process_term(Atomic):-

atomic(Atomic),

!,

write(Atomic), write(' is atomic.'), nl.

process_term(Variable):-

var(Variable),

!,

write(Variable), write(' is a variable.'), nl.

process_term(Term):-

compound(Term),

write(Term), write(' is a compound term.‘), nl.

Page 39: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

39

assert/1, asserta/1, and assertz/1

Asserting facts (most common)assert(Fact)

Asserting rulesassert( (Head :- Body) ).

asserta/1 adds the new clause at the front of the predicate

assertz/1 adds the new clause at the end of the predicate

assert/1 leaves the order unspecified

Page 40: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

40

Built-In: retract/1

retract(Goal) removes the first clause that matches Goal.

On REDO, it will remove the next matching clause, if any.

Retract facts:retract(Fact)

Retract rules:retract( (Head :- Body) ).

Page 41: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

41

Built-in: retractall/1

retractall(Head) removes all facts and rules whose head matches.

Could be implemented with retract/1 as:

retractall(Head) :-

retract(Head),

fail.

retract(Head):-

retract( (Head :- _Body) ),

fail.

retractall(_Head).

Page 42: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

42

Built-In: abolish(Predicate/Arity)

abolish(Predicate/Arity) is almost the same as

retract(Predicate(Arg1, …, ArgN))

except that abolish/1 removes all knowledge about the predicate, where retractall/1 only removes the clauses of the predicate.

Page 43: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

43

Aggregation: findall/3.

findall/3 is a meta-predicate that collects values from multiple solutions to a Goal:

findall(Value, Goal, Values)

findall(Child, parent(james, Child), Children)

Prolog has other aggregation predicates setof/3 and bagof/3, but we’ll ignore them for now.

Page 44: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

44

findall/3 and assert/1

findall/3 and assert/1 both let you preserve information across failure.:- dynamic solutions/1.findall(Value, Goal, Solutions):-

retractall(solutions/1),assert(solutions([])),call(Goal),retract(solutions(S)),append(S, [Value], NextSolutions),assert(solutions(NextSolutions)),fail.

findall(_Value, Goal, Solutions):-solutions(Solutions).

Page 45: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

45

Special Syntax III: Operators

Convenience in writing terms

We’ve seem them all over already:union([Element|RestSet1], Set2, [Element|SetUnion]):-

union(RestSet1, Set2, SetUnion),

\+ member(Element, SetUnion),

!.

This is just an easier way to write the term:‘:-’(union([Element|RestSet],Set2,[Element|SetUnion]),

‘,’(union(RestSet1,Set2,SetUnion),

‘,’(‘\+’(member(Element, SetUnion),

!)))

Page 46: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

46

Operators (cont)

Operators can come before their arguments (prefix) \+

Or between their arguments (infix) , + is <

Of after their arguments (postfix) Prolog doesn’t use any of these (yet)

The same Operator can be more than one type :-

Page 47: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

47

Precedence and Associativity

Operators also have precedence 5 * 2 + 3 = (5 * 2) + 3

Operators can be associative, or not,

Left associative or right associative

Explicit parenthesization can override defaults for associatiativity and precendence

Page 48: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

48

Built-in: current_op/3

current_op/3 gives the precedence and associativity of all current operators.

current_op(Precedence, Associativity, Operator)

where Precedence in an integer 1-1200

and Associativity is of fx or fy for prefix operators xf or yf for postfix operators xfx, xfy, yfx, yfy for infix operators

Page 49: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

49

Associativity

These atoms: fx, fy, xf, yf, xfx, xfy, yfx, yfy draw a “picture” of the associativity of the operator: The location of the f tells if the operator is prefix, infix,

or postfix. x means that the argument must be of lower precedence y means that the argument must be of equal or lower

precedence. A y on the left means the operator is left associative A y on the right means the operator is right associative

Page 50: 1 History Automatic Theorem Proving Robinson 1965 “PROgramming in LOGic” Kowalski, 1974 Deduction as computation “Prolog”, Colmerauer, 1973 Edinburgh Prolog,

50

Creating new operators

Built-in op/3 creates new operators

op(+Precedence, +Associativity, +Operator)

:- op(700, xfx, equals).

:- op(650, fx, $).

:- op(650, xf, cents).

$Dollars equals Cents cents :-

Cents is 100 * Dollars.