About prolog History Symbolic Programming Language Logic Programming Language Declarative Programming Language
Prolog Program A Prolog program is defined by a set of Predicates Each Predicate has a unique Functor and Arity parent(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 Factor a Rule
Defining relations by facts parent( pam, bob). % Pam is a parent of Bob parent( tom, bob). parent( tom, liz). parent( bob, ann). parent( bob, pat). parent( pat, jim). pam lizbob jim patann tom
Term A Term is either: Atomic, Variable, or Compound 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 Variables start with a capital letter or _ character 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 ). A compound term is a structure with a functor and N arguments
Defining relations by rules Rules have: A condition part (body) the right-hand side of the rule A conclusion part (head) the left-hand side of the rule Syntax: concl(…) :- cond1(…), …, condN(…).
Rules Define the “ offspring ” relation: Fact: offspring( liz, tom). Rule: offspring( Y, X) :- parent( X, Y). pam lizbob jim patann tom X Y parentoffspring
mother( X, Y) :- parent( X, Y), female( X). grandparent( X, Z) :- parent( X, Y), parent( Y, Z). parent X Y mother female Z parent X Y grandparent
Facts: declare things that are always true facts are clauses that have a head and the empty body Rules: declare things that are true depending on a given condition rules have the head and the (non-empty) body Questions: the user can ask the program what things are true questions only have the body ?- parent( bob, pat). ?- parent( bob, pat), parent( pat, jim). pam lizbob jim patann tom
Structural Induction and Recursion e.g. simple arithmetic using compound terms to represent integers: s(0).% 1 s(s(0)).% 2 s(s(s(0))).% 3 … is_number(0). Is_number(s(N)):- number(N).
predecessor( X, Z):- parent( X, Z). predecessor( X, Z):- parent( X, Y), predecessor( Y, Z). parent X Y predecessor Z parent X Y predecessor Y2 parent X Y1 predecessor Z parent
How Prolog works To answer a question, Prolog tries to satisfy all the goals. To satisfy a goal means to demonstrate that the goal is true, assuming that the relations in the program is true. Prolog accepts facts and rules as a set of axioms, and the user ’ s question as a conjectured theorem. For now; lets have a pragmatic view…
To find out when our question can be true; Prolog tries to prove it; to satisfy all the goals. To satisfy a goal means to demonstrate that the goal is true, assuming that the relations in the program are true. So our program -facts and rules we defined- would be axioms, and the user ’ s question is the conjectured theorem. A rough sketch of prolog’s algorithm would be: prove(Query): if Query is empty succeed else choose it’s first goal, G. for each clause C of the program whose head matches G: make NewQuery from Query by replacing G with C’s body. prove(NewQuery).
And-Or Tree Note that in each step we are free to choose which clause to use (OR). When we choose the clause; we must satisfy all of it’s conditions (AND).
parent( pam, bob). parent( tom, bob). parent( tom, liz). parent( bob, ann). parent( bob, pat). parent( pat, jim). predecessor( X, Z) :- parent( X, Z). % Rule pr1 predecessor( X, Z) :- parent( X, Y), % Rule pr2 predecessor( Y, Z). predecessor( tom, pat) predecessor( bob, pat) parent( tom, Y) predecessor( Y, pat) parent( tom, pat) parent( bob, pat) no By rule pr1 By rule pr2 By fact parent( tom, bob) Y = bob By rule pr1 yes ?- predecessor( tom, pat).
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 2 nd argument of a dotted pair. [a,b,c] = [a|[b,c]]. [Head|Tail] is a common expression for dividing a list into
% 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. Example: list/1
% 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). Example: delete/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). Example: append/3
pure Prolog vs 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 reversibility of your program.
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.
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