0% found this document useful (0 votes)
34 views46 pages

Untitled

This document outlines solutions to various logic programming problems involving family relations, backtracking, lists, and other concepts. It provides sample code for defining predicates to represent family members and their relationships, using facts and rules. It also gives examples of solving problems using backtracking to try multiple solutions, manipulating lists, representing concepts like circuits using predicates and clauses, and more.

Uploaded by

maqddus butool
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
34 views46 pages

Untitled

This document outlines solutions to various logic programming problems involving family relations, backtracking, lists, and other concepts. It provides sample code for defining predicates to represent family members and their relationships, using facts and rules. It also gives examples of solving problems using backtracking to try multiple solutions, manipulating lists, representing concepts like circuits using predicates and clauses, and more.

Uploaded by

maqddus butool
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 46

Table of Contents

Basics........................................................................................................................................................2
Solutions...............................................................................................................................................3
1.1    Family Relations.......................................................................................................................3
1.1.1    Facts.....................................................................................................................................3
1.1.2    Predicates............................................................................................................................3
1.1.3    More Family Relations......................................................................................................3
Solution 1.1......................................................................................................................................4
1.2    A Simple Thought (Basic Inference)....................................................................................5
Solution 1.2......................................................................................................................................6
1.3    A Small World (Knowledge Representation)......................................................................6
Solution 1.3......................................................................................................................................6
2    Backtracking.......................................................................................................................................8
Solutions................................................................................................................................................8
2.1    Banknote Change.......................................................................................................................8
Solution 2.1........................................................................................................................................8
2.2    The 4-Color Problem..................................................................................................................9
Solution 2.2......................................................................................................................................10
2.3    Europe........................................................................................................................................10
Solution 2.3......................................................................................................................................12
3.1    Family Relations........................................................................................................................12
Solution 3.1......................................................................................................................................13
3.2    Factorial and Fibonacci............................................................................................................13
Solution 3.2......................................................................................................................................14
3.3    List Manipulations.....................................................................................................................14
Solution 3.3......................................................................................................................................15
3.4    A Complex Bicycle....................................................................................................................18
Solution 3.4......................................................................................................................................19
4.1    Means of Transport...................................................................................................................21
Solution 4.1......................................................................................................................................22
4.2    Problems with Insulators..........................................................................................................23
Solution 4.2......................................................................................................................................24
4.3    Resistor Network (Representation by Terms).......................................................................25
Solution 4.3......................................................................................................................................25
4.4    Digital Circuits (Representation by Clauses).........................................................................25
Solution 4.4......................................................................................................................................26
5.1    A Tennis Tournament...............................................................................................................27
Solution 5.1......................................................................................................................................28
5.2    Three Friends............................................................................................................................29
Solution 5.2......................................................................................................................................29
5.3    The N Queens Problem...........................................................................................................29
5.3.1 Generate and Test................................................................................................................29
5.3.2 Stepwise Generate and Test...............................................................................................31
6.1    Higher-order Predicates...........................................................................................................32
Solution 6.1......................................................................................................................................32
6.2    Memoization..............................................................................................................................33
Solution 6.2......................................................................................................................................34
6.3    User Interaction.........................................................................................................................35
Solution 6.3......................................................................................................................................35
6.4    Counter.......................................................................................................................................37
Solution 6.4......................................................................................................................................38
6.5    Transformation of Facts into List Arguments.........................................................................38
Solution 6.5......................................................................................................................................39
7.1    Car Driving in Switzerland........................................................................................................40
Solution 7.1......................................................................................................................................41
7.2    Two Canisters............................................................................................................................42
Solution 7.2......................................................................................................................................42
7.3    River Crossing...........................................................................................................................43
Solution 7.3......................................................................................................................................44
7.4    A Robot.......................................................................................................................................44
Solution 7.4......................................................................................................................................45
Basics

Solutions

1.1    Family Relations

1.1.1    Facts

Describe a real family as a list of facts of the following form:

father( f, c) /* f is father of child c */

mother( m, c) /* m is mother of child c */

man( m) /* m is man */

woman( w) /* w is woman */

1.1.2    Predicates

Define the following predicates:

parent( P, C) /* P is father or mother of C */

parents( F, M, C) /* F is father, M is mother of C */

child( C, P) /* C is child of P */

son( S, P) /* S is son of P */

daughter( D, P) /* D is daughter of P */

grandfather( GP, GC) /* GV is grandfather of GC */

grandmother( GM, E /* GM is grandmother of E */

grandchild( GC, G) /* GC is grandchild of G */

brother( B, SB) /* B is brother of sibling SB */

sister( S, SB) /* S is sister of sibling SB */

uncle( U, N) /* U is uncle of N */

aunt( A, N) /* A is aunt of N */

woman( w) /* w is woman */

1.1.3    More Family Relations

Define further family relations (e.g. niece, cousin, spouse (!), ...) und test them.

Remark:
The goal X \= Y with the predefined operator \= succeeds, if and only if X and Y are not equal (more
precisely: if they do not unify).

Solution 1.1

woman(queen_elizabeth_II).

mother(queen_elizabeth_II, prince_charles).

mother(queen_elizabeth_II, princess_anne).

mother(queen_elizabeth_II, prince_andrew).

mother(queen_elizabeth_II, prince_edward).

man(duke_philip).

father(duke_philip, prince_charles).

father(duke_philip, princess_anne).

father(duke_philip, prince_andrew).

father(duke_philip, prince_edward).

man(prince_charles).

father(prince_charles, prince_william).

father(prince_charles, prince_henry).

woman( princess_anne).

man( prince_andrew).

man( prince_edward).

woman(princess_diana).

mother(princess_diana, prince_william).

mother(princess_diana, prince_henry).

man(prince_william).
man(prince_henry).

/* 1.2 */

parent( Father, Child) :- father( Father, Child).

parent( Mother, Child) :- mother( Mother, Child).

parents( Father, Mother, Child) :-

father( Father, Child), mother( Mother, Child).

child( Child, Parent) :- parent( Parent, Child).

son( S, P) :- child( S, P), man( S).

daughter( D, P) :- child( D, P), woman( D).

grandfather( GP, Grandchild) :-

parent( P, Grandchild), father( GP, P).

grandmother( GM, Grandchild) :-

parent( P, Grandchild), mother( GM, P).

grandchild( Grandchild, G) :-

parent( P, Grandchild), parent( G, P).

brother( Brother, Sibling) :-

parents( Father, Mother, Brother),

parents( Father, Mother, Sibling),

man( Brother), Brother \= Sibling.

sister( Sister, Sibling) :-

parents( Father, Mother, Sister),

parents( Father, Mother, Sibling),

woman( Sister), Sister \= Sibling.

uncle( U, N) :- parent( P, N), brother( U, P).

aunt( A, N) :- parent( P, N), sister( A, P).

1.2    A Simple Thought (Basic Inference)


People wish to live in piece. Men, women and children are people. I am a man (a woman). Therefore I
wish to live in peace.

Use Prolog to prove this statement!

Solution 1.2

wish_to_live_in_peace( X) :- people( X).

people( X) :- man( X).

people( X) :- woman( X).

people( X) :- child( X).

man( 'I')

1.3    A Small World (Knowledge Representation)

Fig. 1.1: A Student's Room

Represent this student's room such that the following


queries are possible:

1. Which furniture is in the room?

2. How many doors, windows, tables, ... are in the room?

3. Where is the table, the chair, ... ?

4. What is to the left (right) of the table, ... (with respect to the center of the room)?

5. What is at the wall 2, at the window 1, ... ?

6. What is in the corner 1, ... ?

Hint:

Start with the reprentation of the queries and adapt the reprentation of the room correspondigly. Aim at a
concise program with few facts and many rules.

Solution 1.3

furniture( wardrobe, 1).

furniture( bookshelf, 1).

furniture( bed, 1).

furniture( desk, 1).

furniture( chair, 1).


furniture( X) :- furniture( X, N). /* Query 1: ?- furniture( X) */

number( X, N) :- furniture( X, N). /* Query 2: ?- number( Object,


Number) */

number( door, 1).

number( window, 2).

at( wall_1, wardrobe). /* Query 5: ?- at( At, Object) */

at( wall_1, door).

at( wall_2, bookshelf).

at( wall_2, bed).

at( wall_3, bed).

at( wall_3, window_1).

at( wall_3, desk).

at( wall_4, desk).

at( wall_4, window_2).

at( wall_4, wardrobe).

at( window_1, bed).

at( window_2, desk).

in( corner_1, wardrobe). /* Query 6: ?- in( Place, Object) */

in( corner_3, bed).

in( corner_4, desk).

place( X, P) :- at( P, X). /* Query 3: ?- place( Object, Place)


*/

place( X, P) :- in( P, X).

place( chair, at_desk).


left( door, bookshelf). /* Query 4: ?- left( Object1,
Object2) */

left( bookshelf, bed).

left( bed, desk).

left( desk, wardrobe).

left( wardrobe, door).

right( X, Y) :- left( Y, X).

2    Backtracking

Solutions

2.1    Banknote Change

What are the possibilities to change the 100 Swiss Franc bank note into smaller notes 10 Fr., 20 Fr. and
50 Fr.

Hint: Conceive the predicate

change( N10, N20, N50)

that finds all solutions by backtracking, such that 10*N10 + 20*N20 + 50*N50 = 100. Save the possible
values for N10, N20, N50 as facts, e.g. N10 can be one of 0, 1, 2, .., 10.

Solution 2.1

change( N10, N20, N50) :-

c1( N10), c2( N20), c5( N50),

100 is N10 * 10 + N20 * 20 + N50 * 50.

c5( 0).

c5( 1).

c5( 2).

c2( N) :- c5( N).


c2( 3).

c2( 4).

c2( 5).

c1( N) :- c2( N).

c1( 6).

c1( 7).

c1( 8).

c1( 9).

c1( 10).

2.2    The 4-Color Problem

Find an "admissible" coloring of a map such that all adjacent countries have different colors. It had been
conjectured for a long time that such a coloring is possible with only 4 colors. This conjecture was
formulated precisely by F. Guthrie already in 1852, but proved by K. Appel und W. Haken only in 1976
using a computer program.

Write a Prolog program that finds all admissible colorings of a given map using the colors red, blue,
yellow and green.

Fig. 2.1: A Map

Hint: The map can be specified by the following rules:

map( A, B, C, D, E) :-

adjacent( A, B),

adjacent( A, D),

adjacent( A, E),
adjacent( B, C),

adjacent( B, D),

adjacent( B, E),

adjacent( C, D),

adjacent( C, E),

adjacent( D, E).

The query

?- map( A, B, C, D, E)

should find all admissible colors of the countries by backtracking.

Solution 2.2

map( A, B, C, D, E) :-

adjacent( A, B), adjacent( A, D), adjacent( A, E),

adjacent( B, C), adjacent( B, D), adjacent( B, E),

adjacent( C, D), adjacent( C, E),

adjacent( D, E).

color( red).

color( bue).

color( yellow).

color( green).

adjacent( X, Y) :- color( X), color (Y), X \= Y.

2.3    Europe

Write a database with European countries specifying the area, the population and the neighbors of the
individual countries:

area( austria, 83858).

area( france, 547030).


area( germany, 357021).

area( italy, 301230).

area( liechtenstein, 160).

area( spain, 504851).

area( switzerland, 41290).

area( united_kingdom, 244820).

. . .

population( austria, 8169929).

poulation( france, 63182000).

poulation( germany, 83251851).

poulation( italy, 59530464).

poulation( liechtenstein, 32842).

poulation( spain, 47059533).

poulation( switzerland, 7507000).

poulation( united_kingdom, 61100835).

. . .

neighbor( austria, switzerland).

neighbor( france, switzerland).

neighbor( france, germany).

neighbor( france, spain).

neighbor( germany, switzerland).

neighbor( italy, switzerland).

neighbor( liechtenstein, switzerland).

. . .

Enhance the database with deduction rules, e.g.

density( S, D) /* D ist die population density of the state S */

such that the following queries are possible:

1. Which state is a neighbor of Switzerland?

2. Which state is a neighbor of France?


3. Is there a neighbor of Germany that has a bigger population and a larger area than Germany?

4. Is there a neighbor of Switzerland that has a higher density than Switzerland?

Solution 2.3

density( S, D) :- population( S, E), area( S, F), D is E/F.

neighbors( S1, S2) :- neighbor( S1, S2).

neighbors( S1, S2) :- neighbor( S2, S1).

neighbor_ch( S) :- neighbors( ch, S). /* Query 1 */

neighbor_f( S) :- neighbors( f, S). /* Query 2 */

neighbor_d( S) :- /* Query 3 */

neighbors( d, S),

population( d, ED), population( S, ES),

area( d, FD), area( S, FS),

ES > ED, FS > FD.

neighbor_ch1( S) :- /* Query 4 */

neighbors( ch, S),

density( ch, DCH), density( S, DS), DS > DCH

3.1    Family Relations

Extend the family relations of the Example 1.1 by the following predicates:

ancestor( A, X)

/* A is an ancestor of X */

descendant(D, X)

/* D is a descendant of X */
related( X, Y)

/* X and Y are related */

Solution 3.1

ancestor( A, X) :-

parent( A, X).

ancestor( A, X) :-

parent( P, X),

ancestor( A, P).

descendant( D, X) :-

child( C, X).

descendant( D, X) :-

child( C, X),

descendant( D, C).

/* also: descendant( D, X) :- ancestor( X, D) */

related( X, Y) :-

ancestor( X, Y).

related( X, Y) :-

descendant( X, Y).

related( X, Y) :-

ancestor( Z, X), ancestor( Z, Y), X \= Y.

3.2    Factorial and Fibonacci

Implement the following functions as recursive relations:

factorial( N, F)

/* F is the factorial von N */


fibo(N, F)

/* F is the N-th Fibonacci number:

F(n) = F(n-1) + F(n-2), F(0) = F(1) = 1 */

Solution 3.2

factorial( 0, 1).

factorial( X, Y) :-

X > 0, X1 is X - 1,

factorial( X1, Y1), Y is X*Y1.

fibo( 0, 1).

fibo( 1, 1).

fibo( X ,Y) :-

X > 1, X1 is X-1, X2 is X-2,

fibo( X1, Y1), fibo( X2, Y2), Y is Y1 + Y2.

3.3    List Manipulations

Implement the following predicates:

member(X, Y)

/* X is an element of the list Y */

append( X, Y, Z)

/* the list Z is the list Y "plus" the list X */

reverse( X, Y) /* Y is the list X in reversed order. Implementation using


append */

rev( X, Y)

/* Y is the list X in reversed order. Implementation using accumulated


parameters */
min_list( X, Y)

/* Y is the smallest elemente of the list X */

sum( X, S)

/* S = sum of the elements of the list X */

list_length( X, L) /* L is the length of the list X */

positive( X, Y)

/* Y is the list containing the positive elements (numbers) of the list X */

Try also to implement some more difficult predicates:

flatten( X, Y)

/* Y is the list of the atomic elements that occur in the list X or in the
sublists of X.

Example:

flatten( [a, [b, [c, d]], a], [a, b, c, d, a]).*/

set( X, Y)

/* Y is the list of unique elements of the list X.

Example:

set( [1, 1, 2], [1,2]) */

sort_list( X, Y)

/* Y is the ordered list of the elements the list X.

Implementation using "Insert sort":

step k: X1, X2, ... Xk are already sorted as Y1, Y2, ... Yk

step k+1: Xk+1 is inserted into Y1, Y2, ... Yk at the correct position. */

Solution 3.3

member( X, [ X| _]).
member( X, [ _| Y]) :- member( X, Y).

append( [], Y, Y).

append( [ X1| X], Y, [ X1| Z]) :- append( X, Y, Z).

reverse( [], []).

reverse( [ H| T], L) :- reverse( T, R), append( R, [ H], L).

rev( X, Y) :- rev( X, [], Y). /* accumulator */

rev( [ X1| X], Y0, Y) :- rev( X, [ X1| Y0], Y).

rev( [], Y, Y).

min_list( [ X], X).

min_list( [ X1| Xs], MinX) :-

min_list( Xs, MinXs),

min( X1, MinXs, MinX).

min( X, Y, X) :- X =< Y.

min( X, Y, Y) :- X > Y.

sum( [ X], X).

sum( [ X1| Xs], S1) :-

sum( Xs, S), S1 is S + X1.

list_length( [], 0).

list_length( [ _| Xs], L) :-

list_length( Xs, Ls), L is Ls + 1.

positive( [], []).

positive( [ X1| X], [ X1| Y]) :-


X1 > 0, positive( X, Y).

positive( [ X1| X], Y) :-

X1 =< 0, positive( X, Y).

flatten( [], []).

flatten( [ X1| Xs], Y) :-

flatten( X1, Y1), flatten( Xs, Ys),

append( Y1, Ys, Y).

flatten( X, [ X]) :- not_list( X).

not_list( X) :- X \= [], X \= [ _| _].

set( [], []).

set( [ X1| Xs], Ys) :-

member( X1, Xs), set( Xs, Ys).

set( [ X1| Xs], [ X1| Ys]) :-

not_member( X1, Xs), set( Xs, Ys).

not_member( _, []).

not_member( X, [ Y| Ys]) :-

X \= Y, not_member( X, Ys).

sort_list( [], []).

sort_list( [ X1| Xs], Y) :-

sort_list( Xs, Ys),

insert( X1, Ys, Y).

insert( X, [], [ X]).

insert( X, [ Y1| Ys], [ X, Y1| Ys]) :-

X =< Y1.

insert( X, [ Y1| Ys], [ Y1| Zs]) :-


X > Y1, insert( X, Ys, Zs).

3.4    A Complex Bicycle

A hierarchical structure can be described by the following facts:

structure( c, [c1, c2, ..., cn])

/* Component c consists of the subcomponents c1, .., cn */

element( c)

/* Component c ist elementary, i.e. it cannot be decomposed further */

Write the following predicates:

parts( C, E)

/* The component C consists of the elementary objects E, E is a list. */

part( C, SubC)

/* SubC is an elementary or composed component, that is contained directly or


indirectly in C. */

Check your solution on the example of the bicycle structure:

structure( bicycle, [frame, saddle_area, front_set, wheel, wheel, drive,


brakes]).

structure( frame, [top_tube, down_tube, seat_tube, seat_stay, chain_stay]).

structure( saddle_area, [saddle, seat_post]).

structure( front_set, [handlebar_grip, head_tube, schock_absorber, fork]).

structure( wheel, [spokes, hub, rim, tire, valve]).

structure( drive, [pedal, crank_arm, front_derailleur, rear_derailleur,


chain]).

structure( brakes, [front_brakes, rear_brakes]).

element( saddle_area).

element( down_tube).

element( seat_tube).

element( seat_stay).
element( chain_stay).

element( saddle).

element( seat_post).

element( handlebar_grip).

element( head_tube).

element( schock_absorber).

element( fork).

element( spokes).

element( hub).

element( rim).

element( tire).

element( valve).

element( pedal).

element( crank_arm).

element( front_derailleur).

element( rear_derailleur).

element( chain).

element( front_brakes).

element( rear_brakes).

Solution 3.4

structure( bicycle, [frame, saddle_area, front_set, wheel, wheel, drive,


brakes]).

structure( frame, [top_tube, down_tube, seat_tube, seat_stay, chain_stay]).

structure( saddle_area, [saddle, seat_post]).

structure( front_set, [handlebar_grip, head_tube, schock_absorber, fork]).

structure( wheel, [spokes, hub, rim, tire, valve]).

structure( drive, [pedal, crank_arm, front_derailleur, rear_derailleur,


chain]).

structure( brakes, [front_brakes, rear_brakes]).

element( saddle_area).
element( down_tube).

element( seat_tube).

element( seat_stay).

element( chain_stay).

element( saddle).

element( seat_post).

element( handlebar_grip).

element( head_tube).

element( schock_absorber).

element( fork).

element( spokes).

element( hub).

element( rim).

element( tire).

element( valve).

element( pedal).

element( crank_arm).

element( front_derailleur).

element( rear_derailleur).

element( chain).

element( front_brakes).

element( rear_brakes).

parts( S, Parts) :-

structure( S, Cs),

parts_c( Cs, Parts).

parts_c( [], []).

parts_c( [ C1| Cs], P) :-

parts_c1( C1, P1),


parts_c( Cs, P2),

append( P1, P2, P).

parts_c1( S, [ S] ) :- element( S).

parts_c1( S, P) :- parts( S, P).

part( S, C) :-

structure( S, Cs),

member( C, Cs).

part( S, K) :-

structure( S, Cs),

member( S1, Cs),

part( S1, C).

4.1    Means of Transport

Represent the following "world" in Prolog:

 Public transport: bus, train, airplane, ship.


Private transport: bicycle, motorcycle, car.

 Vehicle: bicycle, motorcycle, car, bus.

 Motor vehicle: vehicle with a motor.

 Bicycle: slow, eco-friendly.

 Car: fast, dangerous, has a petrol engine.

 Bus: rather fast, has a petrol engine.

 Train: fast, has an electric motor.

 Airplane: very fast, has a petrol engine.

 Ship: slow, has a diesel engine.

 Vehicles with a petrol engine are eco-hostile.

 Vehicles with an electric motor are eco-friendly.

 Public transport is safe.

Replenish the "knowledge base" such that the following questions can be answered "correctly" and
"completely":
 Which transport means are fast, which are eco-friendly, which are safe?

 Is the airplane fast? How fast?

 Which means of transport have a motor?

Can your database answer the following question?:

 Which properties has the car?

If not, how should the database be modified to answer this question?

Solution 4.1

transport( X) :- public( X).

transport( X) :- private( X).

public( bus).

public( train).

public( airplane).

public( ship).

private( bicycle).

private( motorcycle).

private( car).

vehicle( bicycle).

vehicle( motorcycle).

vehicle( car).

vehicle( bus).

motor_vehicle( X) :- has_motor( X).

slow( bicycle).

eco-friendly( bicycle).
fast( car, mittel).

dangerous( car).

has_petrolengine( car).

fast( bus, rather).

has_petrolengine( bus).

fast( train, medium).

has_electricmotor( train).

fast( airplane, very).

has_petrolengine( airplane).

slow( ship).

has_dieselmotor( ship).

eco_hostile( X) :- has_petrolengine( X).

eco_hostile( X) :- has_dieselmotor( X).

eco_friendly( X) :- has_electricmotor( X).

safe( X) :- public( X).

has_motor( X) :- has_petrolengine( X).

has_motor( X) :- has_dieselmotor( X).

has_motor( X) :- has_electricmotor( X).

fast( X) :- fast( X, _).

4.2    Problems with Insulators


Express the following knowledge in Prolog:

Power transmission lines are attached to poles using insulators. Breakdowns of insulators can arise in
one of three ways:

1. A flashover arc is a breakdown and conduction of the air around the insulator, causing an arc
along the outside of the insulator. The flashover arc happens when the voltage is too high, e.g.
because of a lightning strike.

2. A puncture arc is a breakdown and conduction of the material of the insulator, causing an electric
arc through the interior of the insulator. The puncture arc happens when the insulator material is
faulty or has cracks. The insulator is damaged and must be replaced.

3. A surface leakage is an undesirable flow of current over the surface of the insulator. It happens
when the surface is dirty and wet. Composite polymer materials are prone to the surface leakage.
When creepage pathes are built the insulators must be replaced.

The following queries should be supported:

 Which are the possibilities for a insulator breakdown?

 What are the possible causes and consequences?

Solution 4.2

breakdown( flashover_arc).

breakdown( puncture_arc).

breakdown( surface_leakage).

cause( flashover_arc, high_voltage).

cause( high_voltage, lightning_strike).

cause( puncture_arc, faulty_material).

cause( puncture_arc, cracky_material).

cause( surface_leakage, 'surface is dirty and wet').

cause( surface_leakage, 'material is composite polymer').

consequence( Cause, Consequence) :- cause( Consequence, Cause).

consequence( puncture_arc, damage).

consequence( damage, 'replace insulator').

consequence( surface_leakage, creepage_path).

consequence( creepage_path, 'replace insulator').


4.3    Resistor Network (Representation by Terms)

A resistor network, in which the resistors are connected in series or in parallel, can be described by a
compound term. For example:

Fig. 4.1: A Resistor Network

A resistor can be specified by the fact resistor( R, V), where V is the resistance of the resistor R
measured in Ohm, e.g. resistor( r1, 5). Define the predicate

res( N, R)

/* R is the resistance of the network N. */

Solution 4.3

res( NW, R) :-

resistor( NW, R).

res( seq( NW1, NW2), R) :-

res( NW1, R1), res( NW2, R2), R is R1 + R2.

res( par( NW1, NW2), R) :-

res( NW1, R1), res( NW2, R2),

S is 1/R1 + 1/R2, R is 1/S.

4.4    Digital Circuits (Representation by Clauses)

Represent the following circuit "adder1" in Prolog:


Fig. 4.2: Digital Circuit "Adder1"

Hint:

adder1( In1, In2, Cin, Out, Cout) :-

xor( In1, In2, A), xor( A, Cin, Out),

... .

Simulate the circuit and check that this is a 1-bit full-adder, i.e.

Out = (In1 + In2 + Cin) mod 2

Cout = (In1 + In2 + Cin) div 2.

Use this 1-bit full-adder to implement a N-bit full-adder with overflow:

adder_overflow( X, Y, Z, OF).

X, Y, Z are lists with N bits starting with the "most significant bit", Z  is the sum of X und Y, and OF  is the
overflow.

Finally implement the N-bit full-adder:

adder( X, Y, Sum).

where Sum is the sum of X  und Y. It is a list with N+1 bits starting with the "most significant bit".

Solution 4.4

adder1( I1, I2, C_in, Out, C_out) :-

xor( I1, I2, X), and( I1, I2, A1), and( X, C_in, A2),

xor( X, C_in, Out), or( A1, A2, C_out).

adder_overflow( [], [], [], 0).


adder_overflow( [ I1| I1s], [ I2| I2s], [ O| Os], Overflow) :-

adder_overflow( I1s, I2s, Os, Carry),

adder1( I1, I2, Carry, O, Overflow).

adder( X, Y, [ OF| Z]) :-

adder_overflow( X, Y, Z, OF).

or( 0, 0, 0).

or( 0, 1, 1).

or( 1, 0, 1).

or( 1, 1, 1).

xor( 0, 0, 0).

xor( 0, 1, 1).

xor( 1, 0, 1).

xor( 1, 1, 0).

and( 0, 0, 0).

and( 0, 1, 0).

and( 1, 0, 0).

and( 1, 1, 1).

5.1    A Tennis Tournament

On a sunny afternoon Adam, Bob, Carlo and Daniel play some tennis matches. The results are recorded
as Prolog facts:

beats( adam, bob).

beats( adam, carlo).

beats( bob, daniel).

beats( carlo, daniel).

The players agree to be classified in 3 categories:


category( S, 1)

/* S won all matches */

category( S, 2)

/* S won some matches and lost some matches */

category( S, 3)

/* S lost all matches */

Implement the predicate category( Player, Category)  in two ways: once using only cut, and once using
only not. Test your implementations using the queries:

1. What is the category of Adam?

2. Which players belong to the category 2?

3. Does Adam belong to the category 1? Does he belong to the category 2? Does he belong to the
(nonexisting) category 4?

4. What is the category of (non-playing) Thomas?

5. Who played and in which category?

Note: Both implementations cannot answer all queries correctly.

Solution 5.1

beats( adam, bill).

beats( adam, carlo).

beats( bill, daniel).

beats( carlo, daniel).

/* 1st Implementation using 'cut' */

category1( S, 2) :- beats( S, _), beats( _, S), !.

category1( S, 3) :- beats( _, S), !.

category1( S, 1) :- beats( S, _), !.

/* 2nd Implementation using 'not' */

/* SWI Prolog uses '\+' for 'not' */


category2( S, 1) :- beats( S, _), \+ beats( _, S).

category2( S, 2) :- beats( S, _), beats( _, S).

category2( S, 3) :- beats( _, S), \+ beats( S, _).

5.2    Three Friends

The three friends Bill, Daniel und Michael live in different cities and have different jobs. Each year they
meet in Zurich, where one of them lives, and take part in the Silvester run. This time Michael was faster
than his friend from Bern and Daniel was faster than the officer. The fastest was the sport teacher as
always. Daniel lives in Basel, and Michael is a doctor.

Who is who ?

Solution 5.2

friends( S) :-

S = [p( _, _, _, 1), p( _, _, _, 2), p( _, _, _, 3)],

member( p( bill, _, _, _), S),

member( p( _, _, zurich, _), S),

member( p( michael, doctor, _, RM), S),

member( p( _, _, bern, RB), S), RM < RB,

member( p( daniel, _, basel, RD), S),

member( p( _, officer, _, RBe), S), RD < RBe,

member( p( _, sport_teacher, _, 1), S).

5.3    The N Queens Problem

N queens should be positioned on a NxN chessboard so that none of them can hit any other in one move.
In chess, a queen can move as far as she pleases, horizontally, vertically, or diagonally.

5.3.1 Generate and Test

The most straigtforward (but inefficient) solution is the "Generate and Test" method, that can be
implemented in Prolog in general as follows:

solve( Problem, Solution) :-


generate( Problem, Solution),

test( Solution).

In the case of the N queens this would be:

solve( N, Position) :-

generate( N, Position),

test( Position).

The predicate generate generates by backtracking all possible positions of the queens and the
predicate test tests whether these positions are admissible.

A position can be represented e.g. as [p(1,D1), p(2,D2), ..., p(N,DN)]. The structure p(1,D1) means that a
queen is in the column 1 and in the row D1, etc. The possible values for D1, D2, ..., DN correspond to the
permutations of the numbers 1, 2, ...N.

queens( N, Pos) :-

list( 1, N, Columns),

permutation( Columns, Rows),

positions( Columns, Rows, Pos),

test( Pos).

positions( [], [], []).

positions( [ X| Y], [ U| V], [ p( X, U)| W]) :- positions( Y, V, W).

test( []).

test( [ Q| R]) :- test1( Q, R), test( R).

test1( _, []).

test1( Q, [ R| S]) :- not_diagonal( Q, R), test1( Q, S).

not_diagonal( p( C1, R1), p( C2, R2)) :-

X is abs( C1 - C2) - abs( R1 - R2), X \= 0.

list( N, N, [ N]).

list( N, M, [ N| Ns]) :- N < M, N1 is N + 1, list( N1, M, Ns).


permutation( [], []).

permutation( [ X| Y], [ U| V]) :-

delete( U, [ X| Y], W), permutation( W, V).

delete( X, [ X| Y], Y).

delete( U, [ X| Y], [ X| V]) :- delete( U, Y, V).

5.3.2 Stepwise Generate and Test

The problem can be solved more efficiently by placing the queens in the columns step by step and
immediately testing whether the placement is admissible. If the placement is not admissible, the
backtracking in the columns is performed to get an admissible placement and only afterwards a new
column is tried. Try to implement this method.

A partial solution with admissible queens in the columns 1, 2, …, k is represented by two lists: a list B with
occupied rows and a list F with free rows.

Example: N = 5, k = 3, B = [1, 3, 5], F = [2, 4].

queens( N, Pos) :-

queens_seq( N, RevPos),

reverse_list(RevPos, Pos).

queens_seq( N, Pos) :-

list( 1, N, Rows),

queens_seq( Rows, [], Pos).

queens_seq( Free, Occupied, Pos) :-

delete( Row, Free, Free1),

test_seq( Row, Occupied),

queens_seq( Free1, [ Row | Occupied], Pos).

queens_seq( [], Occupied, Occupied).

test_seq( D, Ds) :-

test_seq( D, Ds, 1).


test_seq( D, [ D1| Ds], N) :-

not( N is abs( D - D1)),

N1 is N + 1, test_seq( D, Ds, N1).

test_seq( _, [], _).

reverse_list( X, Y) :- reverse_list( X, [], Y). /* accumulator */

reverse_list( [ X1| X], Y0, Y) :- reverse_list( X, [ X1| Y0], Y).

reverse_list( [], Y, Y).

6.1    Higher-order Predicates

Implement the following predicates:

abolish( F, A)

/* erases all predicates with the main functor F and the arity A */

filter( P, X, Y)

/* filters the list X into the list Y according to the predicate P */

Examples:

pos( X) :- X > 0.

neg( X) :- X < 0.

?- filter( pos, [ 1, -1, 2, -2], Y). ⇒ Y = [ 1, 2]

?- filter( neg, [ 1, -1, 2, -2], Y). ⇒ Y = [ -1, -2]

Solution 6.1

abolish( F, A) :- functor( Term, F, A), retract_all( Term).

retract_all( X) :- retract( X), fail.

retract_all( X) :- retract( X :- _), fail.

retract_all( _).

/* Testing */
assert_test :-

assert(test(1)),

assert(test(2)),

assert(test(3) :- test(a, b)),

assert(test(a, b)).

filter( P, [ X| Xs], [ X| Ys]) :-

F =.. [P, X], call( F), !,

filter( P, Xs, Ys).

filter( P, [ _| Xs], Ys) :- filter( P, Xs, Ys).

filter( _, [], []).

pos( X) :- X > 0.

neg( X) :- X < 0.

6.2    Memoization

Fibonacci numbers F(N) can be computed as follows:

fibo( 0, 0).

fibo( 1, 1).

fibo( N, F) :-

N > 1,

N1 is N-1,

N2 is N-2,

fibo( N1, F1),

fibo( N2, F2),

F is F1 + F2.

This method is extremely inefficient because intermediate results are recomputed many times. Avoid this
deficiency by storing the intermediate results using assert.
Note: Another efficient method is the iterative computation (implemented by recursion). To this purpose
two additional arguments for F(N-1) and F(N-2) are introduced, F1 = F(N-1) and F2 = F(N-2). Consider
the iterative implementation in a procedural language:

F2 = 0

F1 = 1

for k = 2 to N do:

Sum = F2 + F1

F2 = F1

F1 = Sum

return F1

Solution 6.2

:- dynamic fibo/2. /* a directive for SWI Prolog */

fibo( 0, 0).

fibo( 1, 1).

fibo( N, F) :-

N > 1, N1 is N - 1, N2 is N - 2,

fibo( N1, F1), fibo( N2, F2), F is F1 + F2,

asserta( fibo( N, F) :- !).

/* Iterative solution */

fibo_iter(Counter, F2, F1, Result) :-

Counter > 0,

Sum is F2 + F1,

F2_new = F1,

F1_new = Sum,

Counter1 is Counter - 1,

fibo_iter(Counter1, F2_new, F1_new, Result).

fibo_iter(0, F2, F1, Result) :-

Result = F1.
fibo_iter(0, 0).

fibo_iter(1, 1).

fibo_iter(N, F) :-

N > 1,

Counter is N - 1,

fibo_iter(Counter, 0, 1, F).

6.3    User Interaction

Write a program for interactive querying the distance between two cities:

?- d( City1, City2).

Suppose that the distances are stored in a database, e.g. :

distance( zuerich, baden, 22).

distance( baden, basel, 83).

...

Take the symmetry of the distance relation into account. If a distance is not known, the system should not
answer NO but it should request the distance from the user and store it for later usage.

The session could look like:

?- d( zuerich, baden).

The distance between zuerich and baden is 22 km.

?- d( zuerich, bern).

I don't know. Please tell me: 110

Thank you. I confirm: The distance between zuerich and bern is 110 km.

?- d( zuerich, bern).

The distance between zuerich and bern is 110 km.

Solution 6.3

:- dynamic dist/3. /* a directive for SWI Prolog */

dist( zuerich, baden, 22).


dist( baden, basel, 83).

/* End Database */

/* Main Goal - type distances into the Prolog console */

distances :-

nl, write( 'Input: d( City1, City2).'),

nl, write( 'Quit: exit.'),

repeat,

nl, write( 'Input: '),

read( Input),

process_input( Input), !.

d( X, Y, D) :- dist( X, Y, D).

d( X, Y, D) :- dist( Y, X, D).

process_input( exit) :- !.

process_input( d( S1, S2)) :- distance( S1, S2, _), fail.

output( S1, S2, D) :-

nl, write( 'The distance between '), write( S1), write( ' and '),
write( S2),

write( ' is '), write( D), write( ' km ').

distance( S1, S2, D) :- d( S1, S2, D), output( S1, S2, D), !.

distance( S1, S2, D) :- ask_user( S1, S2, D), !.

ask_user( S1, S2, D) :-

nl, write( 'I do not know. Please tell me:'),

read( DR), process_answer( S1, S2, D, DR).


process_answer( S1, S2, D, DR) :-

number( DR), !, D = DR, assert( dist( S1, S2, D)),

nl, write( 'Thank you. I confirm:'), output( S1, S2, D).

process_answer( _, _, _, no).

process_answer( _, _, _, eof).

process_answer( S1, S2, D, _) :-

nl, write( '*** Invalid Input ***'), ask_user( S1, S2, D).

6.4    Counter

Implement a counter. A counter has a name and a value, and is manipulated using the following
operations:

init( C, V)

/* The counter C is set up and has the value V. */

get( C, V)

/* Unifies the value of the counter C with V. */

inc( C)

/* Increases the value of C by 1. */

dec( C)

/* Decreases the value of C by 1. */

del( C)

/* The counter C is removed from the database. */

Example.:

?- init( c, 0), inc( c), inc( c), get( c, V).

⇒ V = 2
Solution 6.4

init( C, V) :- retractall( counter( C, _)),

assert( counter( C, V)), !.

get( C, V) :- counter( C, V).

inc( C) :- retract( counter( C, N)), N1 is N + 1,

assert( counter( C, N1)), !.

dec( C) :- retract( counter( C, N)), N1 is N - 1,

assert( counter( C, N1)), !.

del( C) :- retract( counter( C, _)).

6.5    Transformation of Facts into List Arguments

Implement bagof  und setof. The predicate bagof( X, P, B) computes B  ("bag") as a list of elements X, that


satisfy P(X) . Example:

a(4).

a(1).

a(5).

a(3).

a(4).

a(1).

?- bag_of( X, a(X), B). ⇒ B = [4, 1, 5, 3, 4, 1]

?- bag_of( b(c,X), a(X), B). ⇒ B = [[b(c, 4), b(c, 1), b(c, 5), b(c, 3),
b(c, 4), b(c, 1)]

?- bag_of( X, (a(X), X>2), B). ⇒ B = [4, 5, 3, 4]

The list B  can contain duplicate elements. The order of the elements is irrelevant.

The predicate setof(X, P, S)  is similar to bagof, but the list S  is a proper mathematical set without
duplicate elements. Moreover, the list S is sorted according to the relation '<'. Example:
?- set_of( X, a(X), S). ⇒ S = [1, 3, 4, 5]

?- set_of( X, (a(X), X>2), S). ⇒ S = [[3, 4, 5]

Solution 6.5

bag_of( X, P, _) :-

asserta( found( mark)),

call( P),

asserta( found(X)),

fail.

bag_of( _, _, B) :-

collect( [], B).

collect( B, BB) :-

retract( found( X)),

( X == mark -> BB = B

; collect( [ X| B], BB)

), !.

/* The following set_of sorts the element of the list S */

set_of( X, P, S) :-

bag_of( X, P, L),

sort1( L, S).

sort1( [], []).

sort1( [ X1| Xs], Y) :-

sort1( Xs, Ys),

insert1( X1, Ys, Y).


insert1( X, [], [ X]).

insert1( X, [ Y1| Ys], [ X, Y1| Ys]) :- X < Y1.

insert1( X, [ Y1| Ys], [ Y1| Zs]) :- X > Y1, insert1( X, Ys, Zs).

insert1( X, [ X| Ys], [ X| Ys]).

/* Test data */

a(4).

a(1).

a(5).

a(3).

a(4).

a(1).

7.1    Car Driving in Switzerland

A road map can be represented as a set of facts:

road( City1, City2, Distance)

This means that there is a direct road between the cities City1 and City2.

road( zuerich, baden, 22).

road( baden, basel, 83).

road( zuerich, rotkreuz, 39).

road( baden, olten, 43).

road( olten, bern, 67).

road( olten, luzern, 57).

road( olten, basel, 39).

road( rotkreuz, luzern, 18).

road( rotkreuz, schwyz, 26).

road( luzern, altdorf, 39).

road( schwyz, altdorf, 16).

Implement the predicate:


route( X, Y, W, L)

which means that there is a route W  from X  to Y having the length L. W is the ordered list of the cities in
between starting with X.

Solution 7.1

road( zuerich, baden, 22).

road( baden, basel, 83).

road( zuerich, rotkreuz, 39).

road( baden, olten, 43).

road( olten, bern, 67).

road( olten, luzern, 57).

road( olten, basel, 39).

road( rotkreuz, luzern, 18).

road( rotkreuz, schwyz, 26).

road( luzern, altdorf, 39).

road( schwyz, altdorf, 16).

tr( X, Y) :- road( X, Y, _).

tr( X, Y) :- road( Y, X, _).

distance( X, Y, L) :- road( X, Y, L), !.

distance( X, Y, L) :- road( Y, X, L).

path( Start, Start, Route, Route).

path( X, Y, PartialRoute, Route):-

tr( X, Z), not( member( Z, PartialRoute)),

path( Z, Y, [ Z| PartialRoute], Route).

route( Start, Destination, Route, Length) :-

path( Start, Destination, [ Start], RevRoute),

revl( RevRoute, Route, Length).


revl( [ X1| Xs], Y, L) :- revl( Xs, [ X1], Y, 0, L).

revl( [ X1| Xs], [ Y1| Ys], Y, L0, L) :-

distance( X1, Y1, DXY),

L1 is L0 + DXY,

revl( Xs, [ X1, Y1| Ys], Y, L1, L).

revl( [], Y, Y, L, L).

7.2    Two Canisters

There are two canisters. The big one holds 7 liters, the small one 5 liters. How can we achieve 4 liters of
water in the big canister? Only the following actions are possible:

1. Fill a canister completely.

2. Empty a canister.

3. Pour the content of a canister into the other one until the former is empty or the later is full.

Write first a general method for problem solving and apply it afterwards to the specific problem of the two
canisters.

Solution 7.2

solve( Start, Path) :- solve( Start, [Start], Path).

solve( Goal, _, []) :- goal( Goal).

solve( State, Visited, [ T| Path]):-

move( State, NewState, T),

\+ member( NewState, Visited),

solve( NewState, [ NewState | Visited], Path).

write_list( []).

write_list( [ X1| Xs]) :- nl, write( X1), write_list( Xs).


backtrack :- nl, nl, write( 'Further solutions? [y./n.]: '),

read( A), (A = n ; A = no).

/* Two Canisters */

canister :- solve( k( 0, 0), Path),

nl, write_list( Path), backtrack.

goal( k( 4, _)).

move( k( _, Y), k( 7, Y), a( 'fill C7', state_c7( 7))).

move( k( X, _), k( X, 5), a( 'fill C5', state_c7( X))).

move( k( _, Y), k( 0, Y), a( 'empty C7', state_c7( 0))).

move( k( X, _), k( X, 0), a( 'empty C5', state_c7( X))).

move( k( X, Y), k( 0, Y1), a( 'empty C7 into C5', state_c7( 0))) :-

Y1 is Y + X, Y1 =< 5.

move( k( X, Y), k( X1, 5), a( 'fill C5 from C7', state_c7( X1))) :-

X1 is X + Y - 5, X1 >= 0.

move( k( X, Y), k( X1, 0), a( 'empty C5 into C7', state_c7( X1))) :-

X1 is X + Y, X1 =< 7.

move( k( X, Y), k( 7, Y1), a( 'fill C7 from C5', state_c7( 7))) :-

Y1 is X + Y - 7, Y1 >= 0.

7.3    River Crossing

A farmer with a sheep, a goat and a bag of hay wants to cross a river. He has a boat that provides place
only for him and one other object. He should not leave the sheep and the goat unsupervised with the hay.
How can he manage the crossing?

(Hint: the farmer has a portable computer with a Prolog interpreter.


Solution 7.3

river :- start_fl( Start), solve( Start, Path),

nl, write_list( Path), backtrack.

start_fl( f( farmer( L), sheep( L), goat( L), hay( L))) :- L = bank1.

goal( f( farmer( R), sheep( R), goat( R), hay( R))) :- R = bank2.

move( f( farmer( B), sheep( S), goat( Z), hay( H)),

f( farmer( B1), sheep( S1), goat( Z1), hay( H1)),

crossing( from( B), to( B1), with( P))) :-

opposite( B, B1),

( P = sheep, S = B, S1 = B1, Z1 = Z, H1 = H ;

P = goat, Z = B, S1 = S, Z1 = B1, H1 = H ;

P = hay , H = B, S1 = S, Z1 = Z, H1 = B1 ;

P = none, S1 = S, Z1 = Z, H1 = H ),

safe( farmer( B1), sheep( S1), goat( Z1), hay( H1)).

opposite( bank1, bank2).

opposite( bank2, bank1).

safe( farmer( B), sheep( _), goat( _), hay( B)).

safe( farmer( _), sheep( B), goat( B), hay( H)) :- opposite( B, H).

7.4    A Robot

A robot should shut a stopcock in a contaminated room. The robot stands at the door, while the stopcock
is in the opposite corner at the ceiling. He (it) can reach it only if he steps on a movable ramp that is at the
window. The robot can perform the following actions:

1. Walk around

2. Push the ramp

3. Step on the ramp


4. Step down from the ramp

5. Shut the stopcock

6. Open the stopcock

Which actions should the robot perform in order to shut the stopcock?

Hint: Represent the initial state e.g. as

Implement the predicate:

state(

robot( at_door, on_floor),

ramp( at_window),

stopcock( open)).

and the final state as

state(

robot( in_corner, on_ramp),

ramp( in_corner),

stopcock( closed)).

Solution 7.4

robot :- robot0( Start), solve( Start, Path),

write_list( Path), backtrack.

robot0( r( robot( at_door, on_floor), ramp( at_window), stopcock( open))).

goal( r( Robot, Ramp, stopcock( closed))).

move( r( robot( X, on_floor), R, V),

r( robot( Y, on_floor), R, V), walk_to( Y)) :-

position( Y), X \= Y.

move( r( robot( X, on_floor), ramp( X), V),

r( robot( Y, on_floor), ramp( Y), V), push_ramp_to( Y)) :-

position( Y), X \= Y.

move( r( robot( X, on_floor), ramp( X), V),


r( robot( X, on_ramp), ramp( X), V), step_up_ramp).

move( r( robot( X, on_ramp), ramp( X), V),

r( robot( X, on_floor), ramp( X), V), step_down_ramp).

move( r( robot( in_corner, on_ramp), R, stopcock( open)),

r( robot( in_corner, on_ramp), R, stopcock( closed)), close).

move( r( robot( in_corner, on_ramp), R, stopcock( closed)),

r( robot( in_corner, on_ramp), R, stopcock( open)), open).

position( at_door).

position( at_window).

position( in_corner).

You might also like