240 likes | 402 Views
PROLOG. Λίστες. Οι λίστες είναι η σημαντικότερη δομή δεδομένων της Prolog. Μια λίστα είναι ένας δυναμικός μονοδιάστατος πίνακας με στοιχεία του αριθμούς, σύμβολα, σύνθετους όρους ή και άλλες λίστες. Τα στοιχεία μιας λίστας δεν είναι απαραίτητο να είναι του ίδιου τύπου.
E N D
Λίστες • Οι λίστες είναι η σημαντικότερη δομή δεδομένων της Prolog. • Μια λίστα είναι ένας δυναμικός μονοδιάστατος πίνακας με στοιχεία του αριθμούς, σύμβολα, σύνθετους όρους ή και άλλες λίστες. • Τα στοιχεία μιας λίστας δεν είναι απαραίτητο να είναι του ίδιου τύπου. • Τα στοιχεία μιας λίστας τοποθετούνται μέσα σε αγκύλες [ , ] και χωρίζονται μεταξύ τους με κόμμα “ , “ .
Λίστες • Παραδείγματα Λιστών σε Prolog • [maria, 8,ball, house]. • [cat,point(1,2),[a ,b],d ]. • Μια λίστα μπορεί να είναι: • Κενή (δομή χωρίς όρους) η οποία συμβολίζεται με [] • Μια δομή με δύο όρους :την κεφαλή (Head) που είναι το πρώτο στοιχείο της λίστας και την ουρά(tail) που είναι το υπόλοιπο τμήμα της λίστας.
Λίστες • Δύο λίστες ενοποιούνται εφόσον έχουν τον ίδιο αριθμό στοιχείων και τα αντίστοιχα στοιχεία τους μπορούν να ενοποιηθούν.
Λίστες • Το κατηγόρημα member παρακάτω ελέγχει εάν ένα στοιχείο (πρώτο όρισμα) ανήκει σε μία λίστα (το δεύτερο όρισμα): • member(X, [ X | Y ] ). • member(X, [ Head | Tail ] ) :- member(X, Tail). Ερωτήσεις στην Prolog ?- member( 2, [ 1, 2, 3] ). Yes ?- member(4, [ 1, 2, 3 ] ). No ?- member(X, [1, 2, 3]). X=1 X=2 X=3
Λίστες • Το παρακάτω κατηγόρημα, last(X,L) επιστρέφει ως Χ το τελευταίο στοιχείο της λίστας L. • last(X, [X]). • last(X, [ Head | Tail] ):- last(X,Tail). • Μπορούμε να κάνουμε κλήσεις στο last/2 με το πρώτο όρισμα ελεύθερο και το δεύτερο δεσμευμένο. Για παράδειγμα: ?- last( Z, [2, 3, 4] ). Z=4 • Εάν καλέσουμε το κατηγόρημα και με τα δύο ορίσματα δεσμευμένα, η απάντηση που θα πάρουμε θα είναι yes ή no, ανάλογα με το αν το πρώτο όρισμα είναι το τελευταίο στοιχείο της λίστα τους δεύτερου ορίσματος ή όχι
Λίστες • Παραδείγματα: ?- last( 4, [2, 3, 4]) . Yes. ?- last( 1, [2, 3, 4]) . no. • Το κατηγόρημα last θα λειτουργήσει ακόμη και αν το καλέσουμε με το πρώτο όρισμα δεσμευμένο και το δεύτερο ελεύθερο! • Σε αυτή την περίπτωση θα επιστρέψει (άπειρες στο πλήθος) λίστες τωνοποίων το τελευταίο στοιχείο είναι το πρώτο όρισμα. • Μπορούμε ακόμη να το καλέσουμε και με τα δύο ορίσματα ελεύθερα. • Σε αυτή την περίπτωση θα επιστρέψει (άπειρες στο πλήθος) λίστες τωνοποίων το τελευταίο στοιχείο είναι ενοποιημένο με το πρώτο όρισμα(μολονότι και τα δύο εξακολουθούν να είναι μεταβλητές).
Λίστες • Η Συνένωση λιστών γίνεται με το κατηγόρημα append(L1,L2,L3), το οποίο επιτυγχάνει όταν η λίστα L3 είναι η ένωση (παράθεση) των L1 και L2. • Η συνένωση μιας λίστας L2 με την κενή λίστα είναι η ίδια λίστα L2. append([ ], L2, L2). • Η συνένωση μιας λίστας ενός στοιχείου και μιας λίστας L2 δίνεται από τον παρακάτω κανόνα: append([A], L2, [A|L2]).
Λίστες • Παραδείγματα • ?-append([a,b],[c,d],[a,b,c,d]). yes • ?-append([a,b,c],[1,2,3],L). L=[a,b,c,1,2,3] • ?-append([a,[b,c],d],[a,[ ],b],L). L=[a,[b,c],d,a,[ ],b] • ?-append(L1,L2,[a,b,c]). L1=[], L2=[a,b,c];L1=[a] L2=[b,c],L1=[a,b] L2=[c]; L1=[a,b,c] L2=[ ]; no
Λίστες • Η προσθήκη ενός στοιχείου στην αρχή μιας λίστας μπορεί να επιτευχθεί με τον ακόλουθο κανόνα • add(List,Element,[Element|List]). Όπου • List είναι η αρχική λίστα • Element είναι το στοιχείο που θέλουμε να προσθέσουμε. • [Element|List] είναι το αποτέλεσμα της προσθήκης.
Λίστες • Η διαγραφή στοιχείων από μια λίστα γίνεται με το κατηγόρημα delete όπου Χ είναι ένα στοιχείο, L1 μια λίστα και L2 η λίστα L1 από την οποία έχουν εμφανιστεί όλες οι εμφανίσεις του Χ. • Οι βασικές ιδέες είναι οι εξής:Εάν η L1 είναι κενή, τότε και η L2 είναι κενή: • delete( X, [ ] , [ ] ). • Εάν το στοιχείο Χ ταυτίζεται με το πρώτο στοιχείο της L1, τότε η L2 ισούται με την ουρά της L1, από την οποία όμως έχουν αφαιρεθεί όλα τα X. • delete( X, [ X | T1], L2) :- delete(X, Τ1, L2).
Λίστες • Θέλουμε να ορίσουμε το κατηγόρημα reverse(L1, L2), το οποίο επιτυγχάνει όταν η λίστα L1 είναι η ανάστροφη της L2. • Οι βασικές ιδέες είναι οι εξής: • Η ανάστροφη της κενής λίστας είναι η κενή λίστα. • reverse( [ ] , [ ] ) . • Για να αναστρέψουμε την L1, ξεχωρίζουμε το πρώτο στοιχείο της H1από την ουρά της T1, αναστρέφουμε την ουρά της και έστω RT1 ηανεστραμμένη ουρά. Τότε η L2 ισούται με την ένωση της RT2 και του στοιχείου H1. • reverse( [ H1 | T1], L2):- reverse(T1, RT1), append(RT1, [H1], L2).
Λίστες • Παραδείγματα ?-reverse([1,2,3,4],[4,3,1,2]). No ?-reverse([1,2,3,4],[4,3,2,1]). Yes ?-reverse([a,b,c,d],L). L=[d, c, b, a].
Προβλημα Σκακίου • Το πρόβλημα του σκακιού αφορά την εύρεση μιας διαδρομής του αλόγου σε μια σκακιερα N*N έτσι ώστε να επισκεφτεί όλα τα τετράγωνα της σκακιέρας χώρις να περάσει από το ίδιο τετράγωνο δυο φορές.Το πρόβλημα έχει λύση για σκακιέρες με μέγεθος μεγαλύτεροή ίσο από 5 *5
Αναπαράσταση καταστάσεων • Ο πιο απλός τρόπος αναπαράστασης είναι με τη μορφή λίστας κάθε στοιχείο της οποίας αναπαριστά ένα τετράγωνο με τη μορφή (X,Y) • Η παραπάνω αναπαράσταση μπορεί να αποθηκευτεί σε ένα γεγονός της μορφής: chess_board( [ (1,1),(1,2),…,(5,4),(5,5)]).
Αναπαράσταση Τελεστών • Οι επιτρεπτές κινήσεις του αλόγου για ένα τυχαίο τετράγωνο είναι 8 όπως φαίνεται στο σχήμα: • Από το σχήμα προκύπτει ότι τα πιθανά επόμενα τετράγωνα από μια θέση προκύπτουν μεταβάλλοντας κάθε φορά τις συντεταγμένες κατα (+1,+2),(-1,+2),…(+2,+1).
Κινήσεις στην Σκακίερα • go((Row,Col),(NRow,Ncol,_):- Row > 1, Col > 2, NRow is Row - 1, Ncol is Col – 2. • go((Row,Col),(NRow,Ncol,N):- Row > 1, NRow is Row - 1, Ncol is Col + 2, Ncol =< N. • go((Row,Col),(NRow,Ncol,_):- Row > 2, Col > 1, NRow is Row - 2, Ncol is Col +1.
Κινήσεις στην σκακίερα • go((Row,Col),(NRow,Ncol,N):- Row > 2, NRow is Row -2, Ncol is Col +1, Ncol =< N. • go((Row,Col),(NRow,Ncol,N):- Col > 2, NRow is Row -2, Ncol is Col -2, Ncol =< N. • go((Row,Col),(NRow,Ncol,N):- Col > 2, NRow is Row +1, Ncol is Col +2, Ncol =< N, NRow =< N.
Κινήσεις στην σκακίερα • go((Row,Col),(NRow,Ncol,N):- Col > 1, NRow is Row +2, Ncol is Col -1, NRow =< N. go((Row,Col),(NRow,Ncol,N):- NRow is Row +2 Ncol is Col +1, NCol =< N, NRow =< N.
Κινήσεις στην Σκακίερα • Πλήρης τελεστής κίνησης είναι: • Move(Here,Table,Next,NewTable,N):- go(Here,Next,N), delete(Next,Table,NewTable). here είναι το τετράγωνο που βρίσκεται το άλογο την δεδομένη χρονική στιγμή. Next το επόμενο τετράγωνο στο οποιο θα μετακινηθεί το άλογο. Table είναι η λίστα όλων τετραγώνων που απομένουν να επισκεφτεί. NewTable είναι η λίστα που προκύπτει αν από την Table αφαιρέσουμε το τετράγωνο Next.
Αλγόριθμος κατά Βάθος • Κατά Βάθος • Kn_tour([],_,[],_). • Kn_tour(Table,Here,[Next|Answer],N):-Move(Here,Table,Next,NewTableN),Kn_tour(NewTable,Next,Answer,N). • Η πρωτη είναι τερματική συνθήκη δηλαδή δηλωνει ότι δεν απομένουν άλλα τετράγωνα • Η Δεύτερη είναι μια αναδρομική κλήση που επαναλαμβάνεται μέχρι να βρεθεί λύση.
Αναζήτηση Κατά Βάθος • Chess_board([(1,1)|Table]),Kn_tour(Table,(1,1),Answer,5). • Απάντηση στη Prolog • [(2,3),(1,5),(3,4),(2,2),(1,4),(3,5),(5,4),(4,2),(2,1),(1,3),(2,5),(3,3),(4,1),(5,3),(4,5),(2,4),(1,2),(3,1),(5,2),(4,4),(3,2),(5,1),(4,3),(5,5)]
Αλγόριθμός Κατά Βάθος • dfs(State, Solution, Solution):- goal(State). dfs(State, PathSoFar, Solution):- not(goal(State)), operator(State,Child), not(member(Child, PathSoFar)), dfs(Child, [Child|PathSoFar], Solution). godfs(Solution):- initial_state(IS), dfs(IS, [IS], Solution1), reverse(Solution1,Solution).