Προς το περιεχόμενο

prolog


Rumpelstiltskin

Προτεινόμενες αναρτήσεις

Καλησπέρα, έχω καποιες απορίες σχετικά με τη prolog. 

Συγκεκριμένα, πως μπορώ να περάσω στοιχεία σε μια δομή trie?

 

εχω βρει αυτο https://www.swi-prolog.org/pldoc/man?section=trie αλλά η ερωτηση μου είναι πρακτική. εστω ότι θελω μια δομη trie  με την ονομασια, πχ trie_test, και θελω να του περασω πχ την τιμή πχ 1234, πως το κανω; και στη συνεχεια να μπορω να προσθεσω νεες τιμες στο trie 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Άσχετο...και δεν θέλω να υποννοησω τίποτα αλλά γνωρίζεις ότι συζητάς για την μακράν πιο νεκρή γλώσσα...αν είναι μάθημα καλώς... ειδάλλως προς ενημέρωση πριν κάνα 2 χρόνια που έτυχε να το δω.... Παγκοσμίως υπήρχε μόνο 1 αγγελία για θέση Prolog.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

1 ώρα πριν, Rumpelstiltskin είπε

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

Καλό κουράγιο και εγώ όταν την είχα με μαντεψιές την περάσαμε...

Με μια γρήγορη ανάγνωση που την έκανα στο λινκ που έδωσες ...νομίζω η Insert Κάνει την δουλειά που θέλεις...

Και πες στον καθηγητή να κάνει μια αναζήτηση για δουλειά στην Prolog...Να μην σας πρήζει...

Πέρα απο κάτι "μνημεία" διαχείρισης αεροδρομίων (respect) ...δεν έχει μείνει πουθενά αλλού...όχι τίποτα άλλο μου αρέσει που τα συγκεκριμένα προγράμματα έφτασαν σε τερατωδεις διαστάσεις (1 εκ. γραμμές +)

  • Like 2
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

την insert παλευα και γω, αλλα κατι κανω λαθος μαλλον ή γενικα κατι παει στραβα με τη γλωσσα αυτη 😛 

τεσπα, θα συνεχισω και αυριο το ψαξιμο μου

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Φίλε γεια σου !

 Το ερώτημά σου σχετικά με τα tries το είδα χθες βράδυ περίπου ώρα 12 και την ώρα εκείνη νύσταζα πάρα πολύ για να γράψω ο,τιδήποτε.
 Κατ' αρχήν τα tries είναι δενδρικές δομές τέτοιες ώστε κάθε κόμβος ν' αποθηκεύει ένα ζεύγος τιμών δεδομένων. Η μία τιμή λέγεται key και η άλλη λέγεται value.
Ευτυχώς πολλοί μεταγλωττιστές της Prolog ενσωματώνουν έτοιμα κατηγορήματα, τόσο για τη δημιουργία, όσο και για τη διαπέραση αυτών των δομών.
Δεν νομίζω ο καθηγητής σου να ζητάει να υλοποιήσεις αυτά τα κατηγορήματα μόνος σου στην Prolog. Προφανώς απλά ζητάει να ξέρεις να τα χρησιμοποιείς.
Ένας απ'  τους πιο γνωστούς μεταγλωττιστές που τα έχει όλ' αυτά ενσωματωμένα είναι ο μεταγλωττιστής SWI Prolog, τον οποίον χρησιμοποιούσαμε κι εμείς στο πανεπιστήμιο.
 Έφτιαξα λοιπόν με τη SWI Prolog μια τέτοια δομή, την ονόμασα Trie_Test όπως ζήτησες, πέρασα τρία τυχαία ζεύγη κλειδιού-τιμής και μετά απλά τα τύπωσα.
Να θυμάσαι πάντα ότι πριν κάνουμε ο,τιδήποτε άλλο, πρέπει πρώτα να ζητήσουμε τη δημιουργία της δενδρικής δομής στη μνήμη με το κατηγόρημα trie_new.
Για να δουλέψει ο κώδικας, απλά γράψε go. στο προτρεπτικό σήμα του μεταγλωττιστή της Prolog.

go :- trie_new(Trie_test), trie_insert(Trie_test,1,1234),
      trie_insert(Trie_test,2,5678),trie_insert(Trie_test,3,9001),
      write("Three values were inserted in the Tree called Trie_Test"),nl,
      trie_lookup(Trie_test,1,V1),trie_lookup(Trie_test,2,V2),trie_lookup(Trie_test,3,V3),
      write("We will look them up now ..."),nl,nl,
      write("Key = 1, Value = "),write(V1),nl,
      write("Key = 2, Value = "),write(V2),nl,
      write("Key = 3, Value = "),write(V3).

Να θυμάσαι πάντα ότι το κατηγόρημα trie_new δέχεται αποκλειστικά και μόνο ένα όρισμα που είναι το όνομα της νέας δενδρικής δομής που θα δημιουργηθεί. Το κατηγόρημα trie_insert δέχεται 3 ορίσματα. Το πρώτο είναι το όνομα της δενδρικής δομής και τα άλλα δύο είναι το εκάστοτε ζεύγος κλειδιού και τιμής.
 Για να γίνει αναζήτηση δεδομένων μέσα στο δέντρο υπάρχει το κατηγόρημα trie_lookup που δέχεται επίσης τρία ορίσματα. Το πρώτο είναι πάλι το όνομα της δενδρικής δομής. Το δεύτερο και το τρίτο είναι το ζεύγος κλειδιού και τιμής όπως πριν. Μόνο που εδώ έχουμε το δικαίωμα μία απ' τις δύο τιμές του ζεύγους να μην είναι καθορισμένη, ώστε να κάνει την αναζήτηση η Prolog και να τη βρει.
Δηλαδή όταν γράφω μέσα στον κώδικα τη φράση  trie_lookup(Trie_test,2,V2) αυτό πάει να πει «Ψάξε μέσα στη δομή Trie_Test να βρεις το κλειδί 2 και την τιμή που αντιστοιχεί σ' αυτό να την τοποθετήσεις στη μεταβλητή V2«. Δηλαδή το τρίτο όρισμα του κατηγορήματος trie_lookup είναι πάντα όρισμα εξόδου.

Ελπίζω λίγο να βοήθησα,

Ίσως οι άλλοι να έχουν εν μέρει δίκιο, αλλά εγώ αγαπώ πάρα πολύ την Prolog και παίρνω πολύ μεγάλη χαρά να βλέπω ανθρώπους να ασχολούνται μ' αυτή την τόσο διαφορετική γλώσσα. Να δημοσιεύεις εδώ τις απορίες σου κι όλοι θα κάνουμε ό,τι καλύτερο μπορούμε.

Νιάααααααου !

Ο Άσπρος Γάτος

Υ.Γ : Θυμάμαι ότι κάποια στιγμή στις αρχές τις δεκαετίας του 90 που ήμουν μαθητής Γυμνασίου, το θρυλικό περιοδικό PC Master δημοσίευσε ένα άρθρο περί της Turbo Prolog Ver.2 ενός μεταγλωττιστή που είχε κατασκευάσει η Borland. Το άρθρο εξηγούσε τις βασικές διαφορές της Prolog σε σχέση με τις δομημένες γλώσσες κι ο τρόπος γραφής του με είχε συγκινήσει πάρα πολύ. Άρχισα λοιπόν να ασχολούμαι φανατικά με τη γλώσσα τα βράδια όταν τελείωνα τα διαβάσματα του σχολείου. Μετά ξαναβρήκα την Prolog στο πανεπιστήμιο.... Αθάνατες εποχές !!!

  • Like 3
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

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

εγώ έστω πως θελω να αποθηκευω τους αριθμούς με αυτή τη μορφή 
image.png.fd08cb5314b3d53fb99a0c72ee7daf2e.pngΣυγνώμη για τη μορφή του, αλλά ήταν το πιο γρήγορο που μπορουσα να κάνω. και μετα θελω να ψάχνω ας πουμε ακολουθίες. δηλαδη να κοιταζω αν υπαρχει πχ το 4 στο trie. μετα ας πουμε το 43 ή το 87 ή το 100 ή το 4321. 
οπότε δε μπορώ να καταλάβω, στο trie insert ποια πρεπει να είναι η τιμή για το key και ποια για το value. Αν καταλαβα καλά, πχ το 4321 εδω είναι ενα key, και το value του ειναι το 1, αλλά δε μου χρειαζεται εμενα καπου το value απο οτι καταλαβαινω. 
Επίσης, για να το βάλω με αυτη τη μορφή στο trie, θα πρεπει να το αντιστρέψω πρώτα; δηλαδη το trie παίρνει τα δεδομένα ως έχει (1234, ανάποδα απο ότι στο γραφημα που έκανα) και πρέπει να τα αντιστρέψω εγώ (αυτο είναι απλό, δε με πειράζει).

επειδη αρχίζω να μπερδευομαι και γω οπως τα λεω, θα το κάνω πιο απλο, το trie "μοιραζει¨ έτσι "αυτόματα" αριθμούς, χαρακτήρες κτλ, απλά με το insert? οποτε αν εγω διαβασω πχ τον αριθμο 1234 και θελω να τον βαλω με τη μορφη 4321 απλά κανω ενα reverse και μετα το εισαγω στο insert και θα γίνει όπως στο γράφημα πάνω; 

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Καλησπέρα !

Κατ' αρχήν πιστεύω ότι το πιο επεξηγηματικό video που υπάρχει για τη συγκεκριμένη δομή δεδομένων είναι αυτό εδώ. Δες το αν θέλεις :

https://www.youtube.com/watch?v=-urNrIAQnNo

Τα δέντρα αυτά λέγονται και prefix trees και είναι κυρίως κατάλληλα για ν' αποθηκεύουν αλφαριθμητικά για γρήγορη αναζήτηση. Κάθε κόμβος έχει δύο τιμές (key,value). Το λεγόμενο key αποτελεί πρωτεύον κλειδί, δηλαδή δεν μπορεί να επανεμφανιστεί σε άλλο κόμβο μέσα στο ίδιο μονοπάτι. Επίσης όταν ένας κόμβος είναι τερματικός, τότε ό,τι υπάρχει απ' τη ρίζα ως τον κόμβο αυτόν είναι λέξη. Οι αναζητήσεις γίνονται απ' τη ρίζα προς τα κάτω.
 
Αυτά για την ώρα,

Ο Άσπρος Γάτος

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

  • 2 εβδομάδες αργότερα...

πως μπορω να διαβασω εναν αριθμο, πχ 0123 και να τον κρατησει ετσι; δηλαδη να μην τον κανει 123.

θελω να τον βαλω σε μια λιστα, και θελω να ειναι της μορφης [0,1,2,3]

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Γεια !

Άμα τον αριθμό τον έχεις ως integer είμαι 99.99% σίγουρος ότι δεν γίνεται να κρατήσεις το αρχικό μηδέν, ακριβώς γιατί η ύπαρξη ενός αρχικού μηδενικού ψηφίου σ' έναν ακέραιο δεν έχει καμία σημασία.  Άρα φαίνεται στην περίπτωση αυτή ότι μάλλον πρέπει να μπλέξεις με το χειρισμό αλφαριθμητικών της Prolog που κατά τη γνώμη μου είναι μανίκι.
 Άμα όμως θέλεις να παίρνεις έναν απλό ακέραιο αριθμό και να τον κάνεις μία λίστα ψηφίων, τα πράγματα είναι αρκετά εύκολα. Επίσης μπορείς στην κεφαλή της λίστας να προσθέτεις όσα αρχικά μηδενικά θέλεις εσύ.
 Κοίτα το παρακάτω κατηγόρημα που έγραψα και το ονομάζω leading_zeros, γιατί ο στόχος είναι ακριβώς αυτός, δηλ. να «παραγεμίζει» με όσα αρχικά μηδενικά ζητήσεις έναν ακέραιο που θα του δώσεις και μετά να σου τον σερβίρει ως απλή λίστα ψηφίων.
Το πρώτο όρισμα είναι ο αρχικός ακέραιος αριθμός που έχεις. Το δεύτερο όρισμα ορίζει από ποια θέση της λίστας θα ξεκινούν τα σημαντικά ψηφία του αριθμού. Το τρίτο όρισμα είναι το λεγόμενο όρισμα εξόδου στην Prolog, δηλαδή μια άδεια λίστα στην οποία θα τοποθετηθεί ο αριθμός.
Άμα θέλεις δηλαδή να πάρεις το 45 ας πούμε και να το κάνεις 0045 πρέπει να γράψεις :

leading_zeros(45,3,L). ώστε το πρώτο σημαντικό ψηφίο του αριθμού να είναι στην τρίτη θέση από αριστερά. Η Prolog θα σου απαντήσει L = [0,0,4,5].

Ιδού ο κώδικας...

:- use_module(library(clpfd)).
leading_zeros(Number, 0, [Number]) :- Number in 0..9, !.
leading_zeros(Number, N, [Psifio|Psifia]) :-
        Psifio in 0..9,
        N #= N1 + 1,
        Number #= Psifio*10^N + Number1,
        Number1 #>= 0,
        N #> 0,
        leading_zeros(Number1, N1, Psifia), !.
        
Αρχικά φορτώνω τη βιβλιοθήκη clpfd που μου χρειάζεται για το χειρισμό αριθμητικών δεδομένων και στον πρώτο ορισμό λέω ότι άμα το δεύτερο όρισμα είναι μηδέν, τότε αν ο αρχικός αριθμός είναι μονοψήφιος, τον τοποθετούμε σε μία λίστα ως μοναδικό στοιχείο της, χωρίς καμία αλλαγή. Αντίθετα, αν ο αρχικός αριθμός δεν είναι μονοψήφιος και το δεύτερο όρισμα είναι μηδενικό, τότε δεν μπορεί να γίνει κάτι άλλο παρά το κατηγόρημα ν' αποτύχει.
Αλλιώς, δηλ. αν όλα τα ορίσματα είναι φυσιολογικά, τότε προσθέτει στην αρχή της λίστας Ν-1 μηδενικά και απ' τη Ν-οστή θέση και μετά τοποθετεί τον αριθμό και «σερβίρει» ως όρισμα εξόδου όλη τη λίστα.

Καλή σας νύχτα,  πλέον τώρα νυστάζω...
Οι γάτοι τέτοια ώρα πάνε στο καλαθάκι τους,
Αύριο πάλι,
Ο Άσπρος Γάτος

  • Like 1
Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

ποιος ειναι ο πιο αποδοτικος τροπος να ενωσω δύο λιστες. υπάρχει κάτι πιο γρήγορο απο απο το append/3 ? κατι με μικρότερη αλγοριθμική πολυπλολότητα ώστε στο τελικό μου πρόγραμμα να γλιτώνω χρόνο.

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Καλησπέρα !

 Άργησα ν' απαντήσω, το ξέρω αλλά χθες ήταν της Παναγίας και οι γάτοι γιορτάζουν κι αυτοί. Δεν έκατσα καθόλου μπροστά σε υπολογιστή.
Όσο για το βέλτιστο τρόπο ένωσης λιστών, δεν ξέρω να πω πολλά. Γενικά όμως για να ενώσουμε δύο λίστες, σκεπτόμαστε ως εξής.

Δήλωση 1η : Αν η κενή λίστα ενωθεί με μια άλλη λίστα (έστω L1) τότε το αποτέλεσμα της ένωσης θα είναι οπωσδήποτε η λίστα L1. Στην Prolog η κενή λίστα συμβολίζεται με δύο αγκύλες [].
 
unite([],L1,L1).

Όπως ίσως ξέρεις, το πρώτο στοιχείο μιας λίστας λέγεται κεφαλή (head), ενώ όλο το υπόλοιπο λέγεται ουρά (tail). Οι λίστες μπορεί να μην έχουν μουστάκια και τρίχωμα, όμως έχουν κεφαλή και ουρά. Έτσι λοιπόν μια λίστα με κεφαλή έστω Χ και ουρά έστω Τ συμβολίζεται με [Χ|T].

Δήλωση 2η : Έστω μια λίστα με κεφαλή Χ και ουρά Τ. Αν αυτή ενωθεί με μια άλλη λίστα, (έστω L2), τότε η ένωση της αρχικής με την L2 θα 'χει την κεφαλή της αρχικής και μια νέα ουρά (έστω ΝΤ) η οποία ΝΤ θα είναι η ένωση της ουράς Τ της αρχικής λίστας με την L2.

unite([X|T],L2,[X|NT]):- unite(T,L2,NT).

Δηλαδή στο κατηγόρημα unite που έγραψα έχουμε 2 ορίσματα εισόδου (τις 2 λίστες που θέλουμε να ενωθούν) και ένα όρισμα εξόδου, που είναι φυσικά η νέα λίστα. Έτσι αν φορτώσεις αυτές τις 2 γραμμές κώδικα και γράψεις :

unite([w,h,i,t,e],[c,a,t],New_List). η prolog θα απαντήσει New_List = [ w,h,i,t,e,c,a,t].

Αναγκαστικά η Prolog θα διατρέξει και τις 2 λίστες για να τις διαβάσει και να τις ενώσει, οπότε δεν μου φαίνεται να υπάρχει κάποιος πιο αποδοτικός τρόπος απ' αυτόν. Τι να πω.....;

Φιλικά,

Ο Άσπρος Γάτος

Συνδέστε για να σχολιάσετε
Κοινοποίηση σε άλλες σελίδες

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...