© Ευάγγελος Κουράκος Μαυρομιχάλης, 2006
Προηγούμενο | Περιεχόμενα | Επόμενο
 

Δυναμική τροποποίηση προγράμματος

Ένα από τα σημαντικά χαρακτηριστικά της Prolog είναι η δυνατότητα δυναμικής τροποποίησης τόσο των γεγονότων που εισάγουμε στη βάση δεδομένων (μέσω του editor) όσο και των κανόνων. Έτσι ένα πρόγραμμα Prolog μπορεί να προσαρμόζεται δυναμικά ανάλογα με τα νέα δεδομένα που εισάγει ο χρήστης ή γενικότερα ανάλογα με τη κατάσταση του περιβάλλοντος στο οποίο τρέχει.

Η Prolog διακρίνει δύο κατηγορίες γεγονότων (και κανόνων): τα στατικά και τα δυναμικά.

Ένα γεγονός χαρακτηρίζεται στατικό αν το έχουμε εισάγει μέσω του editor. Στα γεγονότα αυτά, η Prolog δεν επιτρέπει καμία αλλαγή (διαγραφή ή εισαγωγή νέων) από τη στιγμή που γίνουν compiled.

Ένα γεγονός ή κανόνας χαρακτηρίζεται δυναμικό σε δύο περιπτώσεις:
(α) αν έχει εισαχθεί από τον χρήστη (μέσω του interpreter) ή από κάποιο κανόνα κατά τη διάρκεια εκτέλεσης του προγράμματος και με την προϋπόθεση ότι το γεγονός αυτό δεν έχει οριστεί προηγουμένως από τον προγραμματιστή (μέσω του editor), είτε
(β) αν έχει οριστεί στην αρχή του προγράμματος ότι το γεγονός ή ο κανόνας αυτός είναι δυναμικός με την εντολή dynamic/1.

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

Παραδείγματα

Έστω ότι έχουμε γράψει στον editor τα παρακάτω γεγονότα και κανόνες και ότι τα έχουμε κάνει compiled:

:- dynamic b/1.
:- dynamic c/1.
a(1).
a(2).
b(1).
b(2).
b(3).
c(X):- a(X),b(X).
c(X):- a(X).
d(X):- a(X),b(X).

Τότε τα γεγονότα b/1 καθώς και οι κανόνες c/1 θεωρούνται δυναμικά (λόγω τις dynamic/1), ενώ τα γεγονότα a/1 και d/1 θεωρούνται στατικά.

Η εισαγωγή νέων δυναμικών γεγονότων ή κανόνων γίνεται με τις ενσωματωμένες εντολές asserta/1 και assertz/1, ενώ η διαγραφή γίνεται με την εντολή retract/1.

Η εντολή asserta/1 εισάγει ένα νέο γεγονός στην αρχή της βάσης δεδομένων, ενώ η εντολή assertz/1 εισάγει ένα νέο γεγονός στο τέλος αυτής.

Για παράδειγμα αν δόσουμε την εντολή:
?- asserta(b(8)).
Τότε το γεγονός b(8) θα εισαχθεί πάνω από τα υπάρχοντα b/1.

Ενώ αν δόσουμε την εντολή:
?- assertz( (c(Y):-a(Y),d(Y)) ).
Τότε ο κανόνας αυτός θα εισαχθεί στο τέλος των κανόνων c/1.

Τέλος αν γράψουμε:
?- retract(b(2)).
Τότε διαγράφουμε το πρώτο γεγονός της βάσης που ταυτοποιείται με το b(2).

Για να ελέγξουμε τη κατάσταση της βάσης εισάγουμε την ακόλουθη εντολή:

?- listing.
a(1).
a(2).
b(8).
b(1).
b(3).
c(X):- a(X),b(X).
c(X):- a(X).
c(Y):-a(Y),d(Y).
d(X):- a(X),b(X).

 

Έστω ότι έχουμε τα παρακάτω γεγονότα και θέλουμε να αθροίσουμε τους αριθμούς που περιέχουν.

a(1).
a(2).
a(10).
a(4).
a(7).

Για να αθροίσουμε τους αριθμούς αυτούς θα κάνουμε χρήση ενός βοηθητικού γεγονότος sum_temp/1 στο οποίο θα κρατάμε το τρέχουν μέγιστο αριθμό καθώς διαβάζουμε ένα-ένα τα γεγονότα.

:-dynamic(sum_temp/1).

sum_temp(0).

sum(_S):-
   a(X), %Kathe mia timi gegonotos
   sumtmp(X), %th prosthetoume sto sum_temp/1.
   fail.

sum(X):-sum_temp(X). %Sto telos epestrefei ti timi tou sum_temp/1.

sumtmp(X):-
   retract(sum_temp(Y)),
   Z is X+Y,
   assert(sum_temp(Z)).


Τελευταία ενημέρωση σελίδας: 10/11/2008