ΠΑΝΕΠΙΣΤΗΜΙΟ ΙΩΑΝΝΙΝΩΝ ΤΜΗΜΑ ΜΗΧΑΝΙΚΩΝ Η/Υ ΚΑΙ ΠΛΗΡΟΦΟΡΙΚΗΣ ΜΑΘΗΜΑ: ΑΡΧΕΣ ΓΛΩΣΣΩΝ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ ΑΚΑΔ. ΕΤΟΣ: 2018-19 ΔΙΔΑΣΚΩΝ: Χ.ΝΟΜΙΚΟΣ 4η Σειρά Εργαστηριακών Ασκήσεων Οι εργαστηριακές ασκήσεις είναι ατομικές. Οι απαντήσεις θα πρέπει να υποβληθούν με turnin, το αργότερο μέχρι την Τετάρτη 22 Μαΐου 2019. Για τη συγγραφή των προγραμμάτων επιτρέπεται να χρησιμοποιήσετε μόνο τα προκαθοριμένα κατηγορήματα και τους προκαθορισμένους τελεστές που αναφέρονται στις σημειώσεις του μαθήματος. Οι ώρες οι οποίες έχουν δεσμευτεί για το εργαστήριο του μαθήματος είναι την Τετάρτη 12-2μμ. Η παρουσία στο εργαστήριο τις παραπάνω ώρες δεν είναι υποχρεωτική. Μπορείτε να έρχεστε στο εργαστήριο τις ώρες αυτές για όποια βοήθεια χρειάζεστε σχετικά με την εκπόνηση των εργαστηριακών ασκήσεων και γενικότερα τον προγραμματισμό στη γλώσσα Prolog, καθώς και για την επίλυση προβλημάτων που παρουσιάζονται κατά τη συγγραφή των προγραμμάτων στο πλαίσιο των εργαστηριακών ασκήσεων. Σημειώνεται ότι σε καμία περίπτωση δεν θα παρέχεται σχετική βοήθεια μέσω e-mail. Για τη συγγραφή των προγραμμάτων συνίσταται να χρησιμοποιήσετε το αρχείο πρότυπο Lab4.pro (που υπάρχει στην ιστοσελίδα του μαθήματος), στο οποίο για κάθε κατηγόρημα που ζητείτε να ορίσετε στις παρακάτω ασκήσεις, υπάρχει ένας κανόνας ο οποίος το ορίζει έτσι ώστε να επιστρέφει πάντα την απάντηση. Για να απαντήσετε στις ασκήσεις αντικαταστήστε τους παραπάνω κανόνες με ένα κατάλληλο σύνολο προτάσεων που να ορίζει το κάθε κατηγόρημα. Δεν θα πρέπει να τροποποιήσετε το όνομα κανενός κατηγορήματος ούτε το πλήθος των ορισμάτων του. Μπορείτε να ορίσετε όσα βοηθητικά κατηγορήματα θέλετε, τα οποία θα χρησιμοποιούνται για τον ορισμό των κατηγορημάτων που σας ζητείται να υλοποιήσετε. Σε καμία περίπτωση δεν θα πρέπει να προσθέσετε άλλα ορίσματα στα κατηγορήματα που σας ζητούνται. Αν χρησιμοποιήσετε προκαθοριμένα κατηγορήματα ή τελεστές που δεν α- ναφέρονται στις σημειώσεις του μαθήματος, η αντίστοιχη άσκηση δεν θα βαθμολογηθεί. Ο έλεγχος της ορθότητας των απαντήσεων θα γίνει με ημι-αυτόματο τρόπο. Σε καμία περίπτωση δεν θα πρέπει ο βαθμολογητής να χρειάζεται να κάνει παρεμβάσεις στο αρχείο που θα υποβάλετε. Συνεπώς θα πρέπει να λάβετε υπόψη τα παρακάτω: 1. Κάθε ένα από τα κατηγορήματα που σας ζητείται να υλοποιήσετε θα πρέπει να έχει το συγκεκριμένο όνομα και το συγκεκριμένο πλήθος ορισμάτων που περιγράφεται στην εκφώνηση της αντίστοιχης άσκησης και που υπάρχει στο αρχείο πρότυπο Lab4.pro. Αν σε κάποια άσκηση το όνομα ή το πλήθος των ορισμάτων δεν συμφωνεί με αυτόν που δίνεται στην εκφώνηση, η άσκηση δεν θα βαθμολογηθεί.
2. Το αρχείο που θα παραδώσετε δεν θα πρέπει να περιέχει συντακτικά λάθη. Αν υπάρχουν τμήματα κώδικα που περιέχουν συντακτικά λάθη, τότε θα πρέπει να τα διορθώσετε ή να τα αφαιρέσετε πριν από την παράδοση. Αν το αρχείο που θα υποβάλετε περιέχει συντακτικά λάθη, τότε ολόκληρη η εργαστηριακή άσκηση θα μηδενιστεί. 3. Οι ερωτήσεις που δίνονται στο τέλος κάθε άσκησης θα πρέπει να επιστρέφουν απάντηση. Αν κάποιες από τις επιστρεφόμενες απαντήσεις δεν είναι σωστές, αυτό θα ληφθεί υπόψη στη βαθμολογία, ωστόσο η άσκηση θα βαθμολογηθεί κανονικά. Αν ωστόσο κάποια από τις παραπάνω ερώτησεις δεν επιστρέφει απάντηση, (π.χ. προκαλείται υπερχείλιση στοίβας, ατέρμονος υπολογισμός ή κάποιο σφάλμα χρόνου εκτέλεσης) τότε ο βαθμός για την υλοποίηση του αντίστοιχου κατηγορήματος θα είναι μηδέν. 4. Κατα τη διόρθωση των ασκήσεων οι βαθμολογητές δεν θα κάνουν χρησιμοποιήσουν ερωτήσεις που εμπεριέχουν τα βοηθητικά κατηγορήματα τα οποία ενδεχομένως θα έχετε ορίσει. Η χρήση των βοηθητικών κατηγορημάτων θα πρέπει να γίνεται μέσα από τα κατηγορήματα που σας ζητείται να υλοποιήσετε. Μετά το τέλος της εκφώνησης κάθε άσκησης δίνονται παραδείγματα ερωτήσεων με τις αντίστοιχες αναμενόμενες απαντήσεις, που μπορείτε να χρησιμοποιήσετε για έλεγχο της ορθότητας των προγραμμάτων σας. Για υποβολή με turnin γράψτε (υποθέτοντας ότι έχετε γράψει το πρόγραμμα στο αρχείο Lab4.pro): turnin Prolog-2@myy401 Lab4.pro
Ασκηση 1. Ορίστε ένα κατηγόρημα q(m,n) σε Prolog το οποίο θα αληθεύει αν και μόνο αν M και N είναι θετικοί ακέραιοι αριθμοί, τέτοιοι ώστε ο N να μπορεί να γραφτεί ως γινόμενο δύο αριθμών που έχουν άθροισμα M.?- q(18,45).?- q(45,18).?- q(4,4).?- q(5,5).?- q(16,64).?- q(12,25).?- q(25,24).?- q(36,120).?- q(100,2499).?- q(100,267).?- q(653,98770).?- q(653,98880).
Ασκηση 2. Με δεδομένους τέσσερεις θετικούς ακέραιους αριθμούς a, n, k, m, με m 2, θέλουμε να κατασκευάσουμε τη λίστα [a n mod m, a n+1 mod m, a n+2 mod m,..., a n+k mod m]. Γράψτε ένα πρόγραμμα σε Prolog το οποίο θα πραγματοποιεί την παραπάνω κατασκευή. Συγκεκριμένα, ορίστε ένα κατηγόρημα makelist(a,n,k,m,l) το οποίο θα αληθεύει αν A,N,K,M είναι θετικοί ακέραιοι αριθμοί, M 2 και L είναι η λίστα [A N mod M, A N+1 mod M, A N+2 mod M,..., A N+K mod M].?- makelist(10,2,1,10000,l). L = [100,1000]?- makelist(2,6,10,100,l). L = [64,28,56,12,24,48,96,92,84,68,36]?- makelist(12345678,3,8,100,l). L = [52,56,68,4,12,36,8,24,72]?- makelist(2,3000,5,7,l). L = [1,2,4,1,2,4]?- makelist(2,555000,5,17,l). L = [1,2,4,8,16,15]?- makelist(2,3000000,5,21,l). L = [1,2,4,8,16,11]?- makelist(142857,98765432,9,100,l). L = [1,57,49,93,1,57,49,93,1,57]
Ασκηση 3. Με δεδομένη μία λίστα L, δύο στοιχεία X και Y και έναν θετικό ακέραιο αριθμό N, θέλουμε να κατασκευάσουμε τη λίστα που προκύπτει εισάγοντας στην L το στοιχείο X μετά από την N-οστή εμφάνιση του Y. Αν το Y εμφανίζεται λιγότερες από N φορές στην L τότε η κατασκευή αποτυγχάνει. Γράψτε ένα πρόγραμμα σε Prolog το οποίο θα πραγματοποιεί την παραπάνω κατασκευή. Συγκεκριμένα, ορίστε ένα κατηγόρημα ins(l,x,y,n,s), το οποίο θα αληθεύει αν η L περιέχει τουλάχιστον N φορές το στοιχείο Y και η S προκύπτει από την L εισάγοντας το X μετά από την N-οστή εμφάνιση του Y.?- ins([a,b,c,a,b,d,a,a,e,f,a],<>,c,1,s). S = [a,b,c,<>,a,b,d,a,a,e,f,a]?- ins([a,b,c,a,b,d,a,a,e,f,a],<>,a,1,s). S = [a,<>,b,c,a,b,d,a,a,e,f,a]?- ins([a,b,c,a,b,d,a,a,e,f,a],<>,a,3,s). S = [a,b,c,a,b,d,a,<>,a,e,f,a]?- ins([a,b,c,a,b,d,a,a,e,f,a],<>,a,5,s). S = [a,b,c,a,b,d,a,a,e,f,a,<>]?- ins([a,b,c,a,b,d,a,a,e,f,a],<>,a,6,s).?- ins([a,b,c,a,b,d,a,a,e,f,a],a,a,2,s). S = [a,b,c,a,a,b,d,a,a,e,f,a]?- ins([a,b,c,a,b,d,a,a,e,f,a],<>,x,1,s).?- ins([a,b,c,a,b,d,a,a,e,f,a],<>,a,0,s).?- ins([],<>,z,1,s).
Ασκηση 4. Με δεδομένη μία λίστα L= [x 1, x 2,..., x n ] μήκους n και μία λίστα ακεραίων I= [i 1, i 2,..., i k ], τέτοια ώστε 1 i 1 < i 2 <... < i k n] θέλουμε να κατασκευάσουμε τη λίστα S= [x i1, x i2,..., x ik ] (δηλαδή τη λίστα που αποτλείται από τα στοιχεία της L, οι θέσεις των οποίων υποδεικνύονται από τα στοιχεία της I). Γράψτε ένα πρόγραμμα σε Prolog το οποίο θα πραγματοποιεί την παραπάνω κατασκευή. Συγκεκριμένα, ορίστε ένα κατηγόρημα pick(l,i,s), το οποίο θα αληθεύει αν L είναι μία λίστα, I είναι μία λίστα θετικών ακεραίων σε γνησίως αύξουσα τάξη, που οι τιμές τους δεν υπερβαίνουν το μήκος της L και S είναι η λίστα που αποτελείται από τα στοιχεία της L τα οποία βρίσκονται στις θέσεις που υποδεικνύουν τα στοιχεία της I.?- pick([a,b,c,d,e,f,g,h],[1],s). S = [a]?- pick([a,b,c,d,e,f,g,h],[8],s). S = [h]?- pick([a,b,c,d,e,f,g,h],[9],s).?- pick([a,b,c,d,e,f,g,h],[],s). S = []?- pick([a,b,c,d,e,f,g,h],[2,4,7],s). S = [b,d,g]?- pick([a,b,c,d,e,f,g,h],[4,1],s).?- pick([a,b,c,d,e,f,g,h],[1,2,3,4,5,6,7,8],s). S = [a,b,c,d,e,f,g,h]?- pick([a,b,c,d,e,f,g,h],[6,7,8,9],s).
Ασκηση 5. Με δεδομένους δύο θετικούς ακέραιους αριθμούς N και M, όπου M N, ονομάζουμε λίστα συνδυασμών των N ανά M μία λίστα που αποτελείται από όλες τις λίστες μήκους M οι οποίες αποτελούνται από ακέραιους αριθμούς μεταξύ 1 και N, διαφορετικούς μεταξύ τους και σε αύξουσα τάξη (δηλαδή όλες τις λίστες της μορφής [k 1, k 2,..., k M ] με 1 k 1 < k 2 <... < k M N, k 1, k 2,..., k M N). Η σειρά των λιστών μήκους M μέσα στη λίστα συνδυασμών μπορεί να είναι οποιαδήποτε και κάθε μία από αυτές θα πρέπει να εμφανίζεται ακριβώς μία φορά. Γράψτε ένα πρόγραμμα σε Prolog το οποίο με δεδομένους θετικούς ακέραιους αριθμούς N και M, όπου M N, θα κατασκευάζει μία λίστα συνδυσμών των N ανά M. Συγκεκριμένα ορίστε ένα κατηγόρημα cmb(n,m,l), το οποίο θα αληθεύει αν N και M είναι θετικοί ακέραιοι αριθμοί με M N και L είναι μία λίστα συνδυασμών των N ανά M. Για έλεγχο χρησιμοποιήστε τις παρακάτω ερωτήσεις (οι σειρά των συνδυασμών στη λίστα μπορεί να είναι διαφορετική από αυτή που φαίνεται στα αποτελέσματα, ωστόσο η σειρά των αριθμών σε κάθε εσωτερική λίστα θα πρέπει να είναι η ίδια):?- cmb(3,1,l). L = [[1],[2],[3]]?- cmb(3,2,l). L = [[1,2],[1,3],[2,3]]?- cmb(3,3,l). L = [[1,2,3]]?- cmb(5,2,l). L = [[1,2],[1,3],[2,3],[1,4],[2,4],[3,4],[1,5],[2,5],[3,5],[4,5]]?- cmb(6,3,l). L = [[1,2,3],[1,2,4],[1,3,4],[2,3,4],[1,2,5],[1,3,5],[2,3,5],[1,4,5],[2,4,5],[3,4,5], [1,2,6],[1,3,6],[2,3,6],[1,4,6],[2,4,6],[3,4,6],[1,5,6],[2,5,6],[3,5,6],[4,5,6]]?- cmb(10,9,l). L = [[1,2,3,4,5,6,7,8,9],[1,2,3,4,5,6,7,8,10],[1,2,3,4,5,6,7,9,10],[1,2,3,4,5,6,8,9,10], [1,2,3,4,5,7,8,9,10],[1,2,3,4,6,7,8,9,10],[1,2,3,5,6,7,8,9,10],[1,2,4,5,6,7,8,9,10], [1,3,4,5,6,7,8,9,10],[2,3,4,5,6,7,8,9,10]]?- cmb(12,2,l). L = [[1,2],[1,3],[2,3],[1,4],[2,4],[3,4],[1,5],[2,5],[3,5],[4,5],[1,6],[2,6],[3,6], [4,6],[5,6],[1,7],[2,7],[3,7],[4,7],[5,7],[6,7],[1,8],[2,8],[3,8],[4,8],[5,8],[6,8], [7,8],[1,9],[2,9],[3,9],[4,9],[5,9],[6,9],[7,9],[8,9],[1,10],[2,10],[3,10],[4,10], [5,10],[6,10],[7,10],[8,10],[9,10],[1,11],[2,11],[3,11],[4,11],[5,11],[6,11],[7,11], [8,11],[9,11],[10,11],[1,12],[2,12],[3,12],[4,12],[5,12],[6,12],[7,12],[8,12],[9,12], [10,12],[11,12]]