40
Examples in XSB Prolog Επεξεργασία και Αναπαράσταση Γνώσης Άνοιξη 2010 Τμήμα Επιστήμης Υπολογιστών Πανεπιστημίου Κρήτης

Examples in XSB Prolog

  • Upload
    rock

  • View
    31

  • Download
    2

Embed Size (px)

DESCRIPTION

Examples in XSB Prolog. Επεξεργασία και Αναπαράσταση Γνώσης Άνοιξη 2010 Τμήμα Επιστήμης Υπολογιστών Πανεπιστημίου Κρήτης. Typing a program on the XSB command line. - PowerPoint PPT Presentation

Citation preview

Page 1: Examples in XSB Prolog

Examples in XSB Prolog

Επεξεργασία και Αναπαράσταση ΓνώσηςΆνοιξη 2010

Τμήμα Επιστήμης Υπολογιστών Πανεπιστημίου Κρήτης

Page 2: Examples in XSB Prolog

2

Typing a program on the XSB command line Ο χρήστης του XSB έχει τη δυνατότητα να εισάγει τις προτάσεις (γεγονότα και

κανόνες) του προγράμματός του χρησιμοποιώντας τη γραμμή εντολών του XSB, π.χ.

| ?- [user]. Enter mode to type predicates & rules.

[Compiling user]

edge(1,2).

edge(2,3).

edge(2,4).

reachable(X,Y) :- edge(X,Y).

reachable(X,Y) :- edge(X,Z), reachable(Z, Y).

end_of_file. Done with terminal mode

[user compiled, cpu time used: 0.0500 seconds]

[user loaded]

yes

Page 3: Examples in XSB Prolog

3

Loading a program in XSB

Έχει επίσης τη δυνατότητα να «φορτώσει» ένα αρχείο που περιέχει το λογικό πρόγραμμα. Αυτό θα πρέπει να έχει κατάληξη .P

| ?- [edges]. Load and run edges.P[edges loaded]

yes

Για να «φορτώσει» ένα αρχείο που βρίσκεται σε διαφορετικό directory γράφετε:

| ?- [‘source/edges’]. Load and run edges.P which is saved in directory ‘source’[edges loaded]

yes

To default directory για τον XSB είναι το: xsb-3.1-win32/config/x86-pc-windows/bin

Για να αυξήσετε το μέγεθος της κονσόλαςδεξί κλικ στην γραμμή εργαλείων Προεπιλογές Διάταξη Μέγεθος παραθύρου

Page 4: Examples in XSB Prolog

4

Making queries and termination

| ?- reachable(X,Y).

X = 1Y = 2;  Type a semi-colon repeatedly

X = 2Y = 3;

X = 2Y = 4;

X = 1Y = 3;

X = 1Y = 4;

no

| ?- halt.  Command to Exit XSBEnd XSB (cputime 0.15 secs, elapsetime 96.23 secs)

Page 5: Examples in XSB Prolog

5

Prolog Program Semantics

Τα προγράμματα στην Prolog μπορούν να γίνουν κατανοητά με δύο τρόπους: δηλωτικά (declaratively) διαδικαστικά (procedurally)

Έτσι αν θεωρήσουμε την πρόταση

P :- Q, R.

αυτή μπορεί να ερμηνευτεί ως εξής: Δηλωτικά: το P είναι αληθές αν το Q είναι αληθές και το R είναι αληθές Διαδικαστικά: Για να αποδειχθεί ότι το P είναι αληθές, πρέπει πρώτα

να αποδείξω πρώτα ότι τo Q είναι αληθές και στη συνέχεια ότι και το R είναι αληθές.

Page 6: Examples in XSB Prolog

6

Loading a program in XSB

Ένα αρχείο μπορεί να περιέχει: export declarations: ορίζουν τα σύμβολα που μπορούν να

χρησιμοποιηθούν από άλλα αρχεία local declarations: ορίζουν τα σύμβολα με τοπική μόνο εμβέλεια import declarations: επιτρέπουν τη χρήση συμβόλων που έχουν

εξαχθεί από άλλα αρχεία

Οι δηλώσεις αυτές μπορούν να γίνουν σε οποιοδήποτε σημείο του προγράμματος και έχουν την ακόλουθη μορφή:

:- export sym1, ...,syml.

:- local sym1, ...,symm.

:- import sym1, ...,symn from module.

όπου το symi έχει τη μορφή functor/arity. π.χ.:- import reachable/2 from edges.

Page 7: Examples in XSB Prolog

7

Useful examples – or , if-then-else

Το λογικό or μπορείτε να το εκφράσετε και ως εξής:

or(A):- (A = a ; A = b ), write('A is a or b').

Προσοχή να μην ξεχνάτε τις παρενθέσεις.

if (X=1) then write(b) else write(d):

a(X):- write(a),

( X = 1 -> write(b) ; write(d) ),

write(c).

Page 8: Examples in XSB Prolog

8

Useful examples - for

Προσοχή να μην ξεχνάτε την συνθήκη τερματισμού.

Call with i(5) Result: 4,3,2,1,0

end condition: N>0

i(0).

i(N) :- N>0, write(N), nl, N1 is N-1, i(N1).

Call with for(0,5) Result: 0,1,2,3,4

end condition Start<End

for(End , End ).

for(Start, End ):- Start<End, write(Start), nl,

Start1 is Start+1, for(Start1,End).

Page 9: Examples in XSB Prolog

9

Dynamic Predicates

Κατηγορήματα Στατικά (static): τροποποιούνται μόνο με reloading του

προγράμματος. Δυναμικά (dynamic): μπορούν να τροποποιηθούν την ώρα που

τρέχει ένα πρόγραμμα.

Για να μπορούμε να χειριστούμε μία δομή δυναμικά, στην αρχή του προγράμματος κάνουμε τη δήλωση: :- dynamic turn/1 ή :- dynamic pred/2.

Στη συνέχεια μπορούμε να προσθέσουμε / αφαιρέσουμε δεδομένα από τη βάση γνώσης με χρήση των:assert(…): εισάγει ένα νέο γεγονός στη μνήμη.retract(…): διαγράφει ένα γεγονός από τη μνήμη.

Page 10: Examples in XSB Prolog

10

XSB library modules – List processing (1/3)

append(?List1, ?List2, ?List3)module: basicsSucceeds if list List3 is the concatenation of lists List1 and List2.

member(?Element, ?List)module: basicsChecks whether Element unifies with any element of list List, succeeding more than once if there are multiple such elements.

memberchk(?Element, ?List)module: basicsSimilar to member/2, except that memberchk/2 is deterministic, i.e. does not succeed more than once for any call.

delete_ith(+Index, +List, ?Element, ?RestList)module: listutilSucceeds if the ith element of the list List unifies with Element, and RestList is List with Element removed.

Page 11: Examples in XSB Prolog

11

XSB library modules – List processing (2/3)

ith(?Index, ?List, ?Element)module: basicsSucceeds if the ith element of the list List unifies with Element. Fails if Index is not a positive integer or greater than the length of List. Either Index and List, or List and Element, should be instantiated at the time of the call.

length(?List, ?Length)module: basicsSucceeds if the length of the list List is Length.

same_length(?List1, ?List2)module: basicsSucceeds if list List1 and List2 are both lists of the same number of elements.

select(?Element, ?L1, ?L2)module: basicsList2 derives from List1 by selecting (removing) an Element non-deterministically.

Page 12: Examples in XSB Prolog

12

XSB library modules – List processing (3/3)

reverse(+List, ?ReversedList)module: basicsSucceeds if ReversedList is the reverse of list List. If List is not a proper list, reverse/2 can succeed arbitrarily many times. It works only one way.

perm(+List, ?Perm)module: basicsSucceeds when List and Perm are permutations of each other. The main use of perm/2 is to generate permutations of a given list. Perm may be partly instantiated.

subseq(?Sequence, ?SubSequence, ?Complement)module: basicsSucceeds when SubSequence and Complement are both subsequences of the list Sequence (the order of corresponding elements being preserved) and every element of Sequence which is not in SubSequence is in the Complement and vice versa.

merge(+List1, +List2, ?List3)module: listutilSucceeds if List3 is the list resulting from ”merging” lists List1 and List2

Page 13: Examples in XSB Prolog

13

Append example

append([],L,L).

append([X|L], M, [X|N]) :- append(L,M,N).

append([1,2],[3,4],X)?

Page 14: Examples in XSB Prolog

14

append([],L,L).

append([X|L],M,[X|N]) :- append(L,M,N).

append([1,2],[3,4],X)? X=1,L=[2],M=[3,4],A=[X|N]

Append example

Page 15: Examples in XSB Prolog

15

append([],L,L).

append([X|L],M,[X|N]) :- append(L,M,N).

append([1,2],[3,4],X)? X=1,L=[2],M=[3,4],A=[X|N]

append([2],[3,4],N)?

Append example

Page 16: Examples in XSB Prolog

16

append([],L,L).

append([X|L],M,[X|N’]) :- append(L,M,N’).

append([1,2],[3,4],X)?

X=2,L=[],M=[3,4],N=[2|N’]append([2],[3,4],N)?

X=1,L=[2],M=[3,4],A=[1|N]

Append example

Page 17: Examples in XSB Prolog

17

append([],L,L).

append([X|L],M,[X|N’]) :- append(L,M,N’).

append([1,2],[3,4],X)?

X=2,L=[],M=[3,4],N=[2|N’]append([2],[3,4],N)?

X=1,L=[2],M=[3,4],A=[1|N]

append([],[3,4],N’)?

Append example

Page 18: Examples in XSB Prolog

18

append([],L,L).

append([X|L],M,[X|N’]) :- append(L,M,N’).

append([1,2],[3,4],X)?

X=2,L=[],M=[3,4],N=[2|N’]append([2],[3,4],N)?

X=1,L=[2],M=[3,4],A=[1|N]

append([],[3,4],N’)? L = [3,4], N’ = L

Append example

Page 19: Examples in XSB Prolog

19

append([],L,L).

append([X|L],M,[X|N’]) :- append(L,M,N’).

append([1,2],[3,4],X)?

X=2,L=[],M=[3,4],N=[2|N’]append([2],[3,4],N)?

X=1,L=[2],M=[3,4],A=[1|N]

append([],[3,4],N’)? L = [3,4], N’ = L

A = [1|N] N = [2|N’]

N’= L L = [3,4]

Answer: A = [1,2,3,4]

Append example

Page 20: Examples in XSB Prolog

20

Building new predicates - Range

Create a list containing all integers within a given range.

:- export range/3.range(I,I,[I]).range(I,K,[I|L]) :- I < K, I1 is I + 1, range(I1,K,L).

% range(I,K,L) :- I <= K, and L is the list containing all % consecutive integers from I to K.

Π.χ.

| ?- range(4, 7, L).

L = [4,5,6,7];

no

Page 21: Examples in XSB Prolog

21

Building new predicates - Slice

Extract a slice from a list.

:- export slice/4.slice([X|_],1,1,[X]).slice([X|Xs],1,K,[X|Ys]) :- K > 1, K1 is K - 1,

slice(Xs,1,K1,Ys).slice([_|Xs],I,K,Ys) :- I > 1, I1 is I - 1, K1 is K - 1,

slice(Xs,I1,K1,Ys).

% slice(L1,I,K,L2) :- L2 is the list of the elements of L1% between index I and index K (both included).

Π.χ.

| ?- slice([19,21,35,43,56,68,77,89.90], 3, 5, L2).

L2 = [35,43,56];

no

Page 22: Examples in XSB Prolog

22

Building new predicates - Split

Split a list into two parts.

:- export split/4.

split(L,0,[],L).split([X|Xs],N,[X|Ys],Zs) :- N > 0, N1 is N - 1,

split(Xs,N1,Ys,Zs).

% split(L,N,L1,L2) :- the list L1 contains the first N elements% of the list L, the list L2 contains the remaining elements.

Π.χ.

| ?- split([1,2,3,4,5,6,7,8,9,10], 3, L1, L2).

L1 = [1,2,3]

L2 = [4,5,6,7,8,9,10];

no

Page 23: Examples in XSB Prolog

23

Building new predicates - Rotate Rotate a list N places to the left.

:- import append/3 from basics.:- import length/2 from basics.:- import split/4 from split.:- export rotate/3.

rotate(L1,N,L2) :- N >= 0, length(L1,NL1), N1 is N mod NL1, rotate_left(L1,N1,L2).

rotate(L1,N,L2) :- N < 0, length(L1,NL1), N1 is NL1 + (N mod NL1),

rotate_left(L1,N1,L2).

rotate_left(L,0,L).rotate_left(L1,N,L2) :- N > 0, split(L1,N,S1,S2),append(S2,S1,L2).

% rotate(L1,N,L2) :- the list L2 is obtained from the list L1% by rotating the elements of L1 N places to the left.

Π.χ.| ?- rotate([1,2,3,4,5,6,7,8], 2, L2).L2 = [3,4,5,6,7,8,1,2];no

Page 24: Examples in XSB Prolog

24

Building new predicates – Random Selection Extract a given number of randomly selected elements from a list.

:- import random/3 from random.:- import length/2 from basics.:- import delete_ith/4 from listutil.:- export rnd_select/3.

rnd_select(_,0,[]).rnd_select([X],1,[X]).rnd_select(Xs,N,[X|Zs]) :- N > 0, length(Xs,L), random(1,L,I),

delete_ith(I,Xs,X,Ys), N1 is N-1, rnd_select(Ys,N1,Zs).

% rnd_select(L,N,R) :- the list R contains N randomly selected % items taken from the list L.

Π.χ.| ?- rnd_select([1,2,3,4,5,6,7,8,9], 5, R).R = [7,2,8,1,4];no

Page 25: Examples in XSB Prolog

25

Building new predicates – Random Permutation

Generate a random permutation of the elements of a list.

:- import length/2 from basics.:- import rnd_select/3 from random_selection.:- export rnd_permu/2.

rnd_permu(L1,L2) :- length(L1,N), rnd_select(L1,N,L2).

% rnd_permu(L1,L2) :- the list L2 is a random permutation of% the elements of the list L1.

Π.χ.

| ?- rnd_permu([1,2,3,4,5,6,7,8,9], L).L = [7,3,5,1,8,2,4,6,9].no

Page 26: Examples in XSB Prolog

26

Eight Queens Problem

Ο στόχος είναι να τοποθετηθούν οχτώ βασίλισσες σε μία σκακιέρα χωρίς να μπορεί να απειλείται κάποια από οποιαδήποτε άλλη. Θα πρέπει επομένως η κάθε βασίλισσα να βρίσκεται σε διαφορετική γραμμή, στήλη και διαγώνιο της σκακιέρας. Η προτεινόμενη λύση αποτελεί μια γενική λύση για σκακιέρες (και αντίστοιχο πλήθος βασιλισσών) οποιουδήποτε μεγέθους.

Αναπαριστούμε τις θέσεις των βασιλισσών με μία λίστα των αριθμών 1-Ν. Για παράδειγμα η λίστα [4,2,7,3,6,8,5,1] σημαίνει ότι η βασίλισσα στην πρώτη στήλη βρίσκεται στη γραμμή 4, η βασίλισσα στη δεύτερη στήλη στη γραμμή 2. κ.ο.κ. Με αυτόν τον τρόπο εξασφαλίζουμε ότι η κάθε βασίλισσα βρίσκεται σε διαφορετική στήλη και γραμμή. Το μόνο που απομένει είναι να γίνει ο έλεγχος της διαγώνιου. Μία βασίλισσα τοποθετημένη στη στήλη Χ και γραμμή Υ καταλαμβάνει δύο διαγώνιους, μία με αριθμό C = X+Y και μία με αριθμό D=X-Y.

Page 27: Examples in XSB Prolog

27

Eight Queens – The Solution

:- import memberchk/2 from basics.:- import range/3 from range.:- import select/3 from basics.

% queens(N,Qs) :- Qs is a solution of the N-queens problemqueens(N,Qs) :- range(1,N,Rs), permu(Rs,Qs), test(Qs,1,[],[]).

permu([],[]).permu(Qs,[Y|Ys]) :- select(Y,Qs,Rs), permu(Rs,Ys).

% test(Qs,X,Cs,Ds) :- the queens in Qs, representing columns X to% N, are not in conflict with the diagonals Cs and Ds; Cs and Ds keep% track of the already occupied diagonals.

test([],_,_,_).test([Y|Ys],X,Cs,Ds) :-

C is X-Y, \+ memberchk(C,Cs),D is X+Y, \+ memberchk(D,Ds),X1 is X + 1,test(Ys,X1,[C|Cs],[D|Ds]).

Page 28: Examples in XSB Prolog

28

Knight’s Tour Problem

Ο στόχος είναι να βρούμε μία πορεία που μπορεί να διαγράψει ένα άλογο σε όλες τις θέσεις μία σκακιέρας αυθαίρετου μεγέθους, χωρίς να επισκεφτεί την ίδια θέση παραπάνω από μία φορές.

Page 29: Examples in XSB Prolog

29

Knight’s Tour – The Solution (1/2)

:- import memberchk/2 from basics.

% knights(N,Knights) :- Knights is a knight's tour on a NxN chessboard knights(N,Knights) :- M is N*N-1, knights(N,M,[1/1],Knights).

% closed_knights(N,Knights) :- Knights is a knight's tour on a NxN % chessboard which ends at the same square where it begun.

closed_knights(N,Knights) :- knights(N,Knights), Knights = [X/Y|_], jump(N,X/Y,1/1).

% knights(N,M,Visited,Knights) :- the list of squares Visited must be% extended by M further squares to give the solution Knights of the% NxN chessboard knight's tour problem.

knights(_,0,Knights,Knights).knights(N,M,Visited,Knights) :- Visited = [X/Y|_], jump(N,X/Y,U/V), \+ memberchk(U/V,Visited), M1 is M-1, knights(N,M1,[U/V|Visited],Knights).

Page 30: Examples in XSB Prolog

30

Knight’s Tour – The Solution (2/2)

% jumps on an NxN chessboard from square A/B to C/Djump(N,A/B,C/D) :- jump_dist(X,Y), C is A+X, C > 0, C =< N, D is B+Y, D > 0, D =< N.

% jump distancesjump_dist(1,2).jump_dist(2,1).jump_dist(2,-1).jump_dist(1,-2).jump_dist(-1,-2).jump_dist(-2,-1).jump_dist(-2,1).jump_dist(-1,2).

Page 31: Examples in XSB Prolog

31

Το πρόβλημα του βοσκού

Το πρόβλημα του βοσκού αποτελεί ένα κλασσικό πρόβλημα λογικής (puzzle).

Σε μια όχθη ενός ποταμού υπάρχουν ένας βοσκός, ένας λύκος ένα πρόβατο και ένα δεμάτι σανός. Η διαθέσιμη βάρκα χωρά μόνο δύο αντικείμενα κάθε φορά. Αν υποθέσουμε ότι σε κάθε στιγμή ο λύκος και το πρόβατο, καθώς και το πρόβατο και το δεμάτι δεν μπορούν να είναι μόνα τους σε μία όχθη (χωρίς τον βοσκό), ποία είναι η ακολουθία κινήσεων η οποία πρέπει να γίνει για να περάσουν όλοι απένταντι;

Το παραπάνω πρόβλημα είναι ουσιαστικά ένα πρόβλημα σχεδιασμού κινήσεων (Planning). Στα προβλήματα της κατηγορίας αυτής, μία λύση είναι η αναζήτηση στο χώρο των καταστάσεων του κόσμου του προβλήματος. Κάθε τέτοια κατάσταση περιγράφει τον "κόσμο" του προβλήματος την συγκεκριμένη χρονική στιγμή. Οι μεταβάσεις από μια συγκεκριμένη κατάσταση σε μια επόμενη γίνονται μέσω τελεστών.

Page 32: Examples in XSB Prolog

32

Επιλογή Αναπαράστασης

Είναι πολλές οι διαθέσιμες επιλογές με τις οποίες μπορούμε να αναπαραστήσουμε το συγκεκριμένο πρόβλημα. Η παρακάτω υλοποίηση χρησιμοποιεί για την περιγραφή της κατάστασης ένα σύνθετo όρο της μορφής:

state(shepherd(A),sheep(B),wolf(C),hey(D))

όπου τα A, B, C, D είναι οι όχθες στις οποίες βρίκονται αντίστοιχα ο βοσκός, το πρόβατο, ο λύκος και το δεμάτι σανός.

Με βάση την παραπάνω αναπαράσταση ορίζονται οι τελεστές, που αντιστοιχούν ουσιαστικά στις κινήσεις που μπορούν να γίνουν για να λυθεί το πρόβλημα.

Page 33: Examples in XSB Prolog

33

Ορισμός Κατηγορημάτων

Το κατηγόρημα move/3 περιγράφει τις επιτρεπτές κινήσεις που μπορούν να γίνουν. Η μεταβλητή State είναι η "τρέχουσα" κατάσταση, η μεταβλητή Move είναι η κίνηση που λαμβάνει χώρα για να προκύψει η νέα κατάσταση που ενοποιείται με την μεταβλητή NewState.

% move/3

% move(State,Move,NewState)

% Move the shepherd

move(state(shepherd(X1),sheep(S),wolf(W),hey(H)), go_to_other_shore(X1,X2), state(shepherd(X2),sheep(S),wolf(W),hey(H))):- opposite(X1,X2).

% Take the sheep to the other side

move(state(shepherd(X1),sheep(X1),wolf(W),hey(H)), move_sheep(X1,X2), state(shepherd(X2),sheep(X2),wolf(W),hey(H))):- opposite(X1,X2).

Page 34: Examples in XSB Prolog

34

Ορισμός Κατηγορημάτων

% Take the wolf to the other side

move(state(shepherd(X1),sheep(S),wolf(X1),hey(H)), move_wolf(X1,X2), state(shepherd(X2),sheep(S),wolf(X2),hey(H))):- opposite(X1,X2).

% Take the hey to the other side

move(state(shepherd(X1),sheep(S),wolf(W),hey(X1)), move_hey(X1,X2), state(shepherd(X2),sheep(S),wolf(W),hey(X2))):- opposite(X1,X2).

Το κατηγόρημα opposite/2 δηλώνει τις δύο απέναντι όχθες.

% opposite/2

% opposite(X1,X2).

opposite(a,b).

opposite(b,a).

Page 35: Examples in XSB Prolog

35

Ορισμός Κατηγορημάτων

Το κατηγόρημα is_valid/1 πετυχαίνει όταν η κατάσταση State είναι επιτρεπτή, δηλαδή δεν παραβιάζει τους περιορισμούς του προβλήματος..

% is_valid/1

% is_valid(State).

is_valid(state(shepherd(X),sheep(X),wolf(_),hey(_))).

is_valid(state(shepherd(X),sheep(_),wolf(X),hey(X))).

Page 36: Examples in XSB Prolog

36

Ορισμός Κατηγορημάτων

Το κατηγόρημα end_state/1 πετυχαίνει όταν η State είναι η τελική κατάσταση, δηλαδή όλα τα αντικείμενα είναι στην όχθη b (θεωρούμε ότι αρχικά όλα τα αντικείμενα είναι στην όχθη a).

% end_state/1

% end_state(State).

end_state(state(shepherd(b),sheep(b),wolf(b),hey(b))).

Page 37: Examples in XSB Prolog

37

Ορισμός Κατηγορημάτων

Το κατηγόρημα solve/3 βρίσκει την σειρά των κινήσεων που πρέπει να γίνουν για να επιλυθεί το πρόβλημα. Ουσιαστικά ο αλγόριθμος αναζήτησης που χρησιμοποιείται είναι η κατα-βάθος αναζήτηση της Prolog.

Η μεταβλητή State είναι η "τρέχουσα" κατάσταση, η μεταβλητή Moves η λίστα των κινήσεων και η Previous_States η λίστα των καταστάσεων τις οποίες έχει "επισκευτεί" μέχρι τώρα η διαδικασία αναζήτησης.

Κάθε νέα κατάσταση που προκύπτει (NextState), δεν πρέπει να ανήκει στην λίστα αυτή για την αποφυγή βρόχων.

% solve/3

% solve(State,Moves,Previous_States)

solve(State,[],_):- end_state(State).

solve(State,[Move|Moves],Previous_States):-

move(State,Move,NextState),

\+ member(NextState,Previous_States),

is_valid(NextState),

solve(NextState,Moves,[NextState|Previous_States]).

Page 38: Examples in XSB Prolog

38

Ορισμός Κατηγορημάτων

Το επόμενο κατηγόρημα τυπώνει στην οθόνη τα μέλη μιας λίστας, και χρησιμοποιείται για να τυπώνει τις κινήσεις στην οθόνη.

% pretty_write/1

% pretty_write(List)

pretty_write([]).

pretty_write([First|Rest]):- write(' -> '), write(First), nl,

pretty_write(Rest).

Το κατηγόρημα run/1, χρησιμοποιείται για να εκτελέσουμε το πρόγραμμα.

run(Moves):-solve(state(shepherd(a),sheep(a),wolf(a),hey(a)),Moves,

[state(shepherd(a),sheep(a),wolf(a),hey(a))]),

pretty_write(Moves),nl.

Page 39: Examples in XSB Prolog

39

Ασκήσεις

(ασκ.1): Δημιουργήστε διαδικασία factorial που θα υπολογίζει το παραγοντικό ενός αριθμού. Π.χ.

?- factorial(4,X).

X=24 (ασκ.2): Δημιουργήστε διαδικασία median που θα υπολογίζει τον μεσαίο μίας

λίστας που περιέχει αριθμούς περιττού πλήθους. Π.χ.

?- median([2,8,6,4,7,9,3],X).

X=6 (ασκ.3): Δημιουργήστε διαδικασία set_equality που θα ελέγχει αν δύο λίστες

περιέχουν τα ίδια στοιχεία (δεν μας ενδιαφέρει η σειρά που έχουν στη λίστα). Π.χ.

?- set_equality([1,2,3],[3,1,2]).

yes

?- set_equality([1,2,3],[3,1]).

no

Page 40: Examples in XSB Prolog

40

Ασκήσεις

(ασκ.4): Λύστε το πρόβλημα των ιεραπόστολων με τους κανίβαλους.

Περιγραφή προβλήματος:Στις όχθες ενός ποταµού υπάρχουν συνολικά τρεις ιεραπόστολοι και τρεις κανίβαλοι έτσι ώστε σε κάθε όχθη να υπάρχει ίσος αριθµός ιεραποστόλων και κανιβάλων. Επίσης, υπάρχει και µια βάρκα σε µια από τις όχθες. Θέλουµε όλοι να µεταφερθούν σε µια όχθη. Όµως, η βάρκα για να κινηθεί χρειάζεται τουλάχιστον ένα άτοµο, χωρά µόνο µέχρι δύο άτοµα και σε καµία περίπτωση δεν πρέπει ο αριθµός των κανιβάλων να είναι µεγαλύτερος από αυτόν των ιεραποστόλων σε κάποια όχθη.

nice link:http://gym-tsepel.ioa.sch.gr/play/problem2.htm