CSE 130: Spring 2012

Logic Programming

Ranjit Jhala, UC San Diego

News

PA5, 6 Issues

Final

Logic Programming

Traditional Languages

Prolog

Logic Programming

Prolog History

Prolog : Original Vision "Expert Systems"

Collection of Facts

Collection of Rules

Queries

Deductions

You don't RUN Prolog, you ASK it QUESTIONS

Declarative Programming

Declarative: Ideal for SEARCHING For Results

Declarative Programming

Ideal for Searching Large Space of Results

Philosophy

Declarative Programming Examples...

Declarative Programming: Orbitz/Expedia/etc.

Collection of Facts

Collection of Rules

Then

Queries

Declarative Programming: Linear Programming

Collection of Facts

Collection of Rules

Query: How many burritos and tacos to maximize profit?

max     2.x + 1.y       /* profit           */
s.t.    x   < 200       /* burrito capacity */
        y   < 400       /* taco    capacity */
        x+y < 300       /* total   capacity */
          0 < x, y      /* must produce!    */  

Declarative Programming

Used heavily in many domains (together with statistical methods)

Prolog: New Way To Think About Programming ...

Prolog: ... Programming As Proving!

Plan

Language

  1. Terms
  2. Facts
  3. Queries (Implementation: Unification)
  4. Rules
  5. Programs (Implementation: Backtracking Search)

Programming

Language: Terms

Prolog Program

... but facts and rules about what ?

Terms are Prolog's way of representing Data

"Tree-like" values, similar to Ocaml ADTs

Four Kinds of Terms

  1. Constants
  1. Atoms
  1. Variables
  1. Compound Terms

Prolog Terms: Constants

Constants the simplest term, representing primitive values

Prolog Terms: Atoms

Atom: any identifier starting with lower-case

Atoms are NOT variables

Prolog Terms: Atoms

Atom: any identifier starting with lower-case

Atoms are not variables

Prolog Terms: Atoms

Atom: any identifier starting with lower-case

Atoms are Uninterpreted Constants (Names)

Prolog Terms: Variables

Variables: any identifier starting with upper-case

Variables are quite special ...

Warning: Upper vs. Lowercase leads to errors

Prolog Terms: Compound Terms

Compound terms are of form atom(term1, term2, term3, ...)

Where each term is one-of

Prolog Terms: Compound Terms

Compound terms are of form atom(term1, term2, term3, ...)

Where each term is one-of

Examples

x(y, z)              % y, z       are atoms
parent(alice, bob)   % alice, bob are atoms
parent(alice, Child) % alice is an atom, Child is a variable

Prolog Terms ARE NOT function calls

Prolog Compound Terms

Prolog Terms: Compound Terms

Compound terms are of form atom(term1, term2, term3, ...)

Each term is one-of

An Ocaml Type For Prolog Terms

type term = Constant of int
          | Atom     of string 
          | Variable of string 
          | Compound of string * term list

QUIZ: An Ocaml Type For Prolog Terms

type term = Constant of int
          | Atom     of string 
          | Variable of string 
          | Compound of string * term list

(Hint: atom = lowercase, variable = uppercase)

Which Ocaml value of type term represents Prolog term parent(alice, bob) ?

A. parent ("alice", "bob")

B. parent (Atom "alice", Atom "bob")

C. [Atom "parent"; Atom "alice"; Atom "bob"]

D. Compound ("parent", [Atom "alice"; Atom "bob"])

E. Compound (Atom "parent", [Atom "alice"; Atom "bob"])

Prolog Compound Terms

Prolog term parent(alice, Charlie) is represented by:

Ocaml Value

Compound ("parent", [Atom "alice"; Var "Charlie"])

Tree

QUIZ: An Ocaml Type For Prolog Terms

type term = Constant of int
          | Atom     of string 
          | Variable of string 
          | Compound of string * term list

(Hint: atom = lowercase, variable = uppercase)

What Ocaml value of type term represents Prolog term factorial(5) ?

A. factorial(5)

B. factorial(Atom 5)

C. 120

D. Constant 120

E. Compound ("factorial", [Constant 5])

Prolog Terms

Prolog term factorial(5) is simply the tree

Prolog Terms

Prolog term factorial(5) is simply the tree

Function Symbols

Prolog Terms = (Tree) Structured Data

Plan

Language

  1. Terms
  2. Facts
  3. Queries (Implementation: Unification)
  4. Rules
  5. Programs (Implementation: Backtracking Search)

Programming

Language: Facts

Language: Facts

Example

The following facts specify a list of parent-child relationships

parent(kim, holly).  
parent(margaret, kim).  
parent(herbert, margaret). 
parent(john, kim).
parent(felix, john).  
parent(albert, felix).

Language: Facts

The following facts specify a list of parent-child relationships

parent(kim, holly).  
parent(margaret, kim).  
parent(herbert, margaret). 
parent(john, kim).
parent(felix, john).  
parent(albert, felix).

Prolog maintains a Database of facts

Predicates = Function Symbols Used For Facts

Language: Facts

The following facts specify a list of parent-child relationships

parent(kim, holly).  
parent(margaret, kim).  
parent(herbert, margaret). 
parent(john, kim).
parent(felix, john).  
parent(albert, felix).

Predicates = Function Symbols Used For Facts

Predicates Are Just Names: No Meaning Or Implementation

Language: Facts

The following facts specify a list of parent-child relationships

parent(kim, holly).  
parent(margaret, kim).  
parent(herbert, margaret). 
parent(john, kim).
parent(felix, john).  
parent(albert, felix).

Predicates Are Just Names: No Meaning Or Implementation

Plan

Language

  1. Terms
  2. Facts
  3. Queries (Implementation: Unification)
  4. Rules
  5. Programs (Implementation: Backtracking Search)

Programming

Running Prolog via Queries

Language: Queries

Standard interface is a REPL shell

$ rlwrap swipl 

130f@ieng6-202]:~:501$ swipl
Welcome to SWI-Prolog (Multi-threaded, 32 bits, Version 5.10.5)
Copyright (c) 1990-2011 University of Amsterdam, VU Amsterdam
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.
Please visit http://www.swi-prolog.org for details.

For help, use ?- help(Topic). or ?- apropos(Word).

?-

Language: Queries

Suppose we have a collection of facts saved in lec-prolog.pl

You can load the facts in ...

?- consult('lec-prolog.pl').
% foo.pl compiled 0.00 sec, 10,640 bytes
true.

... or you can add them one-at-a-time

?- assert(parent(margaret, kim)).

Language: Queries

Once facts are loaded, you query Prolog as follows:

  1. Plg: Prompts you to type a query
  1. You: Type a query
  1. Plg: Tries to prove your query
  1. Plg: Prints out the result (or failure)
  1. Repeat (go to 1)

Lets ask some questions!

Language: Queries

The simplest possible query ...

?- parent(margaret, john).  

... a fact but typed at the prompt.

Language: Queries

The simplest possible query ...

?- parent(margaret, john).  

... a fact but typed at the prompt.

Meaning

O Prolog, is this fact in your Database ... or can it be inferred from your database?

Language: Queries

The simplest possible query ...

?- parent(margaret, john).  

... a fact but typed at the prompt.

Meaning

O Prolog, is this fact in your database ... or can it be inferred from your database?

Prolog Replies

?- parent(margaret, john).
false.

Language: Queries

A slightly different query yields a different result.

Language: Queries

A slightly different query yields a different result.

?- parent(margaret, kim).  
true.

Pfft. Big deal? Is Prolog just a table lookup?!

Things get more interesting when queries have variables ...

Queries With Variables

This is where Prolog starts to depart radically from other paradigms...

?- parent(margaret,X).

Meaning

O Prolog, for which value(s) of X is the fact provable ?

Queries With Variables

This is where Prolog starts to depart radically from other paradigms...

?- parent(margaret,X).

Meaning

O Prolog, for which value(s) of X is the fact provable ?

Prolog Replies

X = kim.

As when it plugs-in kim for X, it can infer parent(margaret, kim).

Queries With Variables

Suppose we flip the query.

?- parent(X, kim).

O Prolog, for which value(s) of X is parent(X, kim) provable ?

Queries With Variables

Suppose we flip the query.

?- parent(X, kim).

O Prolog, who are the parents-of kim?

Queries With Variables

Suppose we flip the query.

?- parent(X, kim).

O Prolog, who are the parents-of kim?

Prolog Replies

?- parent(X, kim).
X = margaret ; % [press ';' if you want another solution]
X = john ;     % [press ';' if you want another solution]
false.         % [thats all folks, no more solutions    ]

Returns all solutions for X that make parent(X, kim) provable.

Queries With Variables

We can write queries with multiple variables.

?- parent(X, Y).

O Prolog, for which pairs X, Y is parent(X, Y) provable?

Queries With Variables

We can write queries with multiple variables.

?- parent(X, Y).

O Prolog, for which pairs X, Y is parent(X, Y) provable?

Prolog Replies

?- parent(X, Y).
X = kim,      Y = holly   ;
X = margaret, Y = kim     ;
X = herbert,  Y = margaret;
X = john,     Y = kim     ;
X = felix,    Y = john    ;
X = albert,   Y = felix   ;
X = albert,   Y = dana    ;
X = felix,    Y = maya    .

Enumerates all facts in the parent database.

QUIZ: Queries With Variables

Suppose we want to know if there are any strange circularities in the database:

Does there exist any person who is their own parent ?

Which of the following encodes the above in Prolog?

A. parent(kim, kim)

B. parent(x, x)

C. parent(X, X)

D. parent(X, Y)

E. parent(Y, X)

Queries are magic!

Queries Work Like Magic

In Java/C# or for that matter ML/Scala/... you would need

Plan

Language

  1. Terms
  2. Facts
  3. Queries (Implementation: Unification)
  4. Rules
  5. Programs (Implementation: Backtracking Search)

Programming

Unification: Prolog's computational heart

Unification: When does one term MATCH another?

Unification

Two Terms Can Be Unified If

We can substitute values for their variables to make the terms identical

Unification

Two terms can be unified if we can substitute values for variables to make the terms identical

Equality Is Unification

In Prolog, when you write (e.g. in a query)

?- term1 = term2.

you are asking whether term1 can be unified with term2.

Unification By Example

Unification: Atoms

Two terms can be unified if we can substitute values for variables to make the terms identical

Example

?- kim = kim.
true.

Two same atoms are trivially unified.

Unification: Atoms

Two terms can be unified if we can substitute values for variables to make the terms identical

Example

?- kim = holly.
false.

Two different atoms can never be unified.

Unification: Compound Terms Are Recursively Unified

Two terms can be unified if we can substitute values for variables to make the terms identical

Example

?- foo(kim) = foo(kim).
true.

As there are no variables, and the terms are already identical.

Example

?- foo(kim) = foo(holly).
false.

As there are no variables, and the terms can never be identical.

Unification: Variables

Two terms can be unified if we can substitute values for variables to make the terms identical

Example

?- X = kim.

Unification: Variables

Two terms can be unified if we can substitute values for variables to make the terms identical

Example

?- foo(X) = foo(kim).

Prolog Responds

?- foo(X) = foo(kim).
X = kim.

QUIZ: Unification With Multiple Variables

Two terms can be unified if we can substitute values for variables to make the terms identical

How does Prolog respond to the following query?

?- foo(X, dog) = foo(cat, Y).

A. false

B. X = cat, Y = cat.

C. X = dog, Y = dog.

D. X = dog, Y = cat.

E. X = cat, Y = dog.

Unification With Multiple Variables

Two terms can be unified if we can substitute values for variables to make the terms identical

?- p(X, dog, X) = p(cat, Y, Y).

Unification With Multiple Variables

Two terms can be unified if we can substitute values for variables to make the terms identical

?- p(X, dog, X) = p(cat, Y, Y).

The top nodes of both trees have same predicate ... go inside.

Unification With Multiple Variables

Two terms can be unified if we can substitute values for variables to make the terms identical

?- p(X, dog, X) = p(cat, Y, Y).

To unify X and cat use substitution X = cat

Unification With Multiple Variables

Two terms can be unified if we can substitute values for variables to make the terms identical

?- p(X, dog, X) = p(cat, Y, Y).

Apply substitution X = cat to both terms. Move on to next leaf...

Unification With Multiple Variables

Two terms can be unified if we can substitute values for variables to make the terms identical

?- p(X, dog, X) = p(cat, Y, Y).

To unify dog and Y use substitution Y = dog ...

Unification With Multiple Variables

Two terms can be unified if we can substitute values for variables to make the terms identical

?- p(X, dog, X) = p(cat, Y, Y).

... and apply substitution throughout both terms.

Unification With Multiple Variables

Two terms can be unified if we can substitute values for variables to make the terms identical

?- p(X, dog, X) = p(cat, Y, Y).

Uh oh, now last leaf has different atoms...

Unification With Multiple Variables

Two terms can be unified if we can substitute values for variables to make the terms identical

?- p(X, dog, X) = p(cat, Y, Y).

... impossible to unify cat and dog. Unification fails.

Unification With Multiple Variables

Two terms can be unified if we can substitute values for variables to make the terms identical

?- p(X, dog, X) = p(cat, Y, Y).
false.

QUIZ: Recursively Unify Subtrees

Two terms can be unified if we can substitute values for variables to make the terms identical

How does Prolog respond to the following unification query?

?- a(W, foo(W, Y), Y) = a(2, foo(X, 3), Z).

A. false. (No unification possible)

B. W = 2, X = 2, Y = 2, Z = 2.

C. W = 2, X = 2, Y = 3, Z = 3.

D. W = 3, X = 3, Y = 2, Z = 2.

C. W = 2, X = 3, Y = 2, Z = 3.

Recursively Unify Subtrees

Two terms can be unified if we can substitute values for variables to make the terms identical

How does Prolog respond to the following unification query?

?- a(W, foo(W, Y), Y) = a(2, foo(X, 3), Z).
  1. Subst W = 2. Query is: a(2, foo(2, Y), Y) = a(2, foo(X, 3), Z).
  1. Subst X = 2. Query is: a(2, foo(2, Y), Y) = a(2, foo(2, 3), Z).
  1. Subst Y = 3. Query is: a(2, foo(2, 3), 3) = a(2, foo(2, 3), Z).
  1. Subst Z = 3. Query is: a(2, foo(2, 3), 3) = a(2, foo(2, 3), 3).
  1. Done!

Recursively Unify Subtrees

Two terms can be unified if we can substitute values for variables to make the terms identical

How does Prolog respond to the following unification query?

?- a(W, foo(W, Y), Y) = a(2, foo(X, 3), Z).
W = 2,
X = 2,
Y = 3,
Z = 3.

QUIZ: Recursively Unify Subtrees

Two terms can be unified if we can substitute values for variables to make the terms identical

How does Prolog respond to the following unification query?

?- a(W, foo(W, Y), Y) = a(2, foo(X, 3), X).


A. false. (No unification possible)

B. W = 2, X = 2, Y = 2, Z = 2.

C. W = 2, X = 2, Y = 3, Z = 3.

D. W = 3, X = 3, Y = 2, Z = 2.

C. W = 2, X = 3, Y = 2, Z = 3.

Recursively Unify Subtrees

Two terms can be unified if we can substitute values for variables to make the terms identical

How does Prolog respond to the following unification query?

?- a(W, foo(W, Y), Y) = a(2, foo(X, 3), X).
  1. Subst W = 2. Query is: a(2, foo(2, Y), Y) = a(2, foo(X, 3), X).
  1. Subst X = 2. Query is: a(2, foo(2, Y), Y) = a(2, foo(2, 3), 2).
  1. Subst Y = 3. Query is: a(2, foo(2, 3), 3) = a(2, foo(2, 3), 2).
  1. 3 = 2 cannot be unified, Fail!

Unification: Powerful Way To Answer Queries

Unification is a Powerful Way To Answer Queries

When we ask

?- parent(margaret, X).  

Prolog checks if the above term can be unified with any known fact (term).

Unification is a Powerful Way To Answer Queries

When we ask

?- parent(margaret, X).  

Prolog checks if the above term can be unified with any known fact (term).

Above Query Has One Solution

?- parent(margaret, X).  
X = kim.

Unification is a Powerful Way To Answer Queries

When we ask

?- parent(X, kim).  

Unification is a Powerful Way To Answer Queries

When we ask

?- parent(X, kim).  

Prolog checks if the above term can be unified with any known fact (term).

Unification is a Powerful Way To Answer Queries

When we ask

?- parent(X, kim).  

Prolog checks if the above term can be unified with any known fact (term).

This Query Has Many Solutions

?- parent(X, kim).  
X = margaret ;
X = john     .

Unification is a Powerful Way To Answer Queries

Finally, when we ask

?- parent(X, Y).  

Unification is a Powerful Way To Answer Queries

Finally, when we ask

?- parent(X, Y).  

Prolog checks if the above term can be unified with any known fact (term).

Unification is a Powerful Way To Answer Queries

Finally, when we ask

?- parent(X, Y).  

Prolog checks if the above term can be unified with any known fact (term).

This Query Has Many Solutions: All known facts

?- parent(X, Y).
X = kim,      Y = holly   ;
X = margaret, Y = kim     ;
X = herbert,  Y = margaret;
X = john,     Y = kim     ;
X = felix,    Y = john    ;
X = albert,   Y = felix   ;
X = albert,   Y = dana    ;
X = felix,    Y = maya    .

Unification Lets Prolog Answer Queries Magically!

Plan

Language

  1. Terms
  2. Facts
  3. Queries (Implementation: Unification)
  4. Rules
  5. Programs (Implementation: Backtracking Search)

Programming

Rules

Digression: Conjunctions, Queries about MANY terms

Conjunction: Comma-separated Sequence of terms

Often useful to ask questions over multiple terms.

Conjunction: Comma-separated Sequence of terms

Often useful to ask questions over multiple terms.

?- parent(margaret, X), parent(X, holly).

Conjunction: Comma-separated Sequence of terms

Often useful to ask questions over multiple terms.

?- parent(margaret, X), parent(X, holly).

Apparently

?- parent(margaret, X), parent(X, holly).
X = kim.

Conjunction: Comma-separated Sequence of terms

Often useful to ask questions over multiple terms.

Conjunction: Comma-separated Sequence of terms

Often useful to ask questions over multiple terms.

?- parent(GGP, GP), parent(GP, P), parent(P, kim).

Note: how we link the terms with a variable to capture relationships.

Conjunction: Comma-separated Sequence of terms

Often useful to ask questions over multiple terms.

?- parent(GGP, GP), parent(GP, P), parent(P, kim).

Note: how we link the terms with a variable to capture relationships.

Prolog finds appropriate unifiers and replies

?- parent(margaret, X), parent(X, holly).
GGP = john,
GP  = felix,
P   = albert.

i.e. john is a great-grandparent following the above chain.

QUIZ: Conjunctions

Which of these queries is true iff margaret and kim are (half-) siblings?

A. parent(margaret, kim)

B. parent(margaret, X), parent(X, kim).

C. parent(kim, X), parent(X, margaret).

D. parent(margaret, X), parent(kim, X).

E. parent(X, margaret), parent(X, kim).

Recap: Conjunctions

Rules

Rules: Complex Predicates from Simple Queries

Format

headQuery :- condQuery1, condQuery2, condQuery3,...

Rules: Complex Predicates from Simple Queries

Format

headQuery :- condQuery1, condQuery2, condQuery3,...


Intuition 1 (Forwards)

Rules: Complex Predicates from Simple Queries

Format

headQuery :- condQuery1, condQuery2, condQuery3,...


Intuition 2 (Backwards)

Rules: Complex Predicates from Simple Queries

An Example: Defining a grandparent predicate

Rules: Complex Predicates from Simple Queries

An Example: Defining a grandparent predicate

grandparent(GP, GC) :- parent(GP, P), parent(P, GC).

Intuition

GP is a grandparent of GC if GP is a parent of P and P is a parent of GC

Rules: Complex Predicates from Simple Queries

An Example: Defining a grandparent predicate

grandparent(GP, GC) :- parent(GP, P), parent(P, GC).

Querying The Defined Predicate

?- grandparent(X, kim). % who are the grandparents of kim
X = herbert ;           % hit ; to see next
X = felix   ;           % hit ; to see next
false.                  % thats it!

Rules: Complex Predicates from Simple Queries

An Example: Defining a grandparent predicate

grandparent(GP, GC) :- parent(GP, P), parent(P, GC).

Querying The Defined Predicate

?- grandparent(X, kim). % who are the grandparents of kim
X = herbert ;           % hit ; to see next
X = felix   ;           % hit ; to see next
false.                  % thats it!

How? Because Prolog can prove

?- parent(herbert, P), parent(P, kim).  %% Solution 1. X = herbert
P = margaret.

?- parent(felix, P), parent(P, kim).    %% Solution 2. X = felix 
P = john .

QUIZ: Complex Predicates from Simple Queries

Which of the following is a valid greatgrandparent predicate?

(Btw, greatgrandparent is the parent of a grandparent.)

% A 
greatgrandparent(X, Y) :- parent(X, Y), grandparent(X, Y). 

% B
greatgrandparent(X, Y) :- parent(X, Z), grandparent(Z, Y). 

% C
greatgrandparent(X, Y) :- grandparent(X, Z), parent(Z, Y).

% D 
greatgrandparent(X, Y) :- parent(X, Z), parent(Z, Y).

% E  
greatgrandparent(X, Y) :- parent(X, Z), parent(Z, Z1), parent(Z1, Y).

Rules: Complex Predicates from Simple Queries

An Example: Defining a greatgrandparent predicate

greatgrandparent(GGP, GC) :- parent(GGP, GP), grandparent(GP, GC).

Rules: Complex Predicates from Simple Queries

An Example: Defining a greatgrandparent predicate

greatgrandparent(GGP, GC) :- parent(GGP, GP), grandparent(GP, GC).

Querying The Defined Predicate

?- greatgrandparent(X, holly). 
X = herbert.

That was our first Prolog program!

Plan

Language

  1. Terms
  2. Facts
  3. Queries (Implementation: Unification)
  4. Rules
  5. Programs (Implementation: Backtracking Search)

Programming

Prolog Programs = Facts + Rules!

Prolog Programs = Facts + Rules!

Facts and Rules are two kinds of clauses

Programs

Prolog Programs = Facts + Rules!

Complex Programs need Complex Predicates with Multiple Rules

  1. Scope
  1. Multiple Rules: Disjunction
  1. Multiple Rules: Recursion

Prolog Programs = Facts + Rules!

Complex Programs need Complex Predicates with Multiple Rules

  1. Scope

  2. Multiple Rules: Disjunction

  3. Multiple Rules: Recursion

Programs = Facts + Rules : Scope

A word about scope.

In the grandparent rule, the variable GP appears twice

greatgrandparent(GGP, GC) :- parent(GGP, GP), grandparent(GP, GC).

Scope: All Variables Are Local To A Single Rule

Programs = Facts + Rules : Scope

A word about scope.

Scope: All Variables Are Local To A Single Rule

Example

foo(P)   :- bar(P).     % There is no connection between P
stuff(P) :- thing(P).   % across the two rules

Prolog Programs = Facts + Rules!

Complex Programs need Complex Predicates with Multiple Rules

  1. Scope

  2. Multiple Rules: Disjunction

  3. Multiple Rules: Recursion

Complex Predicates: Disjunction

Lets write a predicate has_family which is true for persons who

Complex Predicates: Disjunction

Lets write a predicate has_family which is true for persons who

has_family(X) :- parent(X, _). % if X is the parent of some _
has_family(X) :- parent(_, X). % if X is the child of some _

_ is a wildcard or dont-care variable (as in ML, Scala)

Disjunction via Multiple Rules

Complex Predicates: Disjunction

Lets write a predicate has_family which is true for persons who

has_family(X) :- parent(X, _). % if X is the parent of some _
has_family(X) :- parent(_, X). % if X is the child of some _

Executing the Query

?- has_family(holly).
true.  % Second rule fires for holly

?- has_family(mugatu).
false. % Neither rule fires for mugatu 

Complex Predicates: Disjunction

Lets write a predicate has_family which is true for persons who

has_family(X) :- parent(X, _). % if X is the parent of some _
has_family(X) :- parent(_, X). % if X is the child of some _

Can be abbreviated to

has_family(X) :- parent(X, _) ; parent(_, X).

Semicolon ; indicates disjunction.

Prolog Programs = Facts + Rules!

Complex Programs need Complex Predicates with Multiple Rules

  1. Scope

  2. Multiple Rules: Disjunction

  3. Multiple Rules: Recursion

Complex Predicates: Recursion

Lets write a predicate ancestor(Anc, Child) which is true if

Complex Predicates: Recursion

Lets write a predicate ancestor(Anc, Child) which is true if

... if some chain of parent-links holds between Anc and Child.

Base Case

Inductive Case

Complex Predicates: Recursion

Lets write a predicate ancestor(Anc, Child) which is true if

... if some chain of parent-links holds between Anc and Child.

ancestor(Anc, Child) :- parent(Anc, Child).
ancestor(Anc, Child) :- parent(P, Child), ancestor(Anc, P).

Complex Predicates: Recursion

Lets write a predicate ancestor(Anc, Child) which is true if

... if some chain of parent-links holds between Anc and Child.

ancestor(Anc, Child) :- parent(Anc, Child).
ancestor(Anc, Child) :- parent(P, Child), ancestor(Anc, P).

Lets take it out for a spin!

First, lets find descendants (forwards)

?- ancestor(kim, X).
X = holly.

Complex Predicates: Recursion

Lets write a predicate ancestor(Anc, Child) which is true if

... if some chain of parent-links holds between Anc and Child.

ancestor(Anc, Child) :- parent(Anc, Child).
ancestor(Anc, Child) :- parent(P, Child), ancestor(Anc, P).

Lets take it out for a spin!

Next, lets find ancestors (backwards)

?- ancestor(X,kim).
X = margaret  ;
X = john      ;
X = herbert   ;
X = felix     ;
X = albert    .

kim has a long ancestry!

Pretty neat: go forward or back, in just 2 lines...

...Try doing that in any other language!

To be continued...