Τρίτη, Οκτωβρίου 07, 2008

Σενάρια και scheme

Θυμάστε τα σενάρια; Ένας τρόπος να αναπαρασταθεί διαδικαστική γνώση που χρειάζεται να γνωρίζει κάποιος πράκτορας (agent) προκειμένου να δράσει σε ένα καθορισμένο περιβάλλον (πχ σενάριο του εστιατορίου). Έγραψα σε scheme ένα πρόγραμμα που υλοποιεί το σενάριου του κουρείου.

Το πρόγραμμα συντάχθηκε σε DrScheme, version 4.1.

Το πρόγραμμα έχει τρία επίπεδα εννοιολογικής αφαίρεσης. Αρχικά ορίζεται ένα γενικό μοντέλο που περιγράφει την κίνηση (μεταφορά, θέση σώματος) agents μέσα σε ένα χώρο. Ο agent αναπαριστά μια οντότητα που μπορεί να δρα με άλλες οντότητες. Ο χώρος ορίζεται να είναι τριών ειδών : εξωτερικός, κτίριο (με ένα δωμάτιο) και συγκεκριμένο μέρος μέσα στο δωμάτιο. Οι agents μπορούν να είναι 2 ειδών : client και server με τον τελευταίο να έχει επιπλέον σαν ιδιότητα μια λίστα από τις υπηρεσίες που παρέχει. Ακόμα ορίζονται οι γενικές κλάσεις υπηρεσία (service), και συναλλαγή (transaction) που αναπαριστούν βασικές δράσεις που μπορούν να πραγματοποιήσουν οι agents. Αντίστοιχα ορίζονται οι συναρτήσεις TRANS, MOVE, COMM, EXEC που μετακινούν, αλλάζουν τη θέση του σώματος, ζητούν μια δράση από άλλο agent, και εκτελούν μια δράση αντίστοιχα.

Σε δεύτερο επίπεδο ορίζεται το συγκεκριμένο σενάριο (script) του κουρείου. Ορίζονται δηλαδή στιγμιότυπα των παραπάνω κλάσεων :
agent: customer (client) , barber (server),
place: outsidePlace (outside), barbershop (building), desk (interior), workingSeat (interior), waitingSeat (interior),
service: shave, hairwash, haircut,
transaction: payment,
που αρχικοποιούνται σε default τιμές. Ακόμα ορίζονται σκηνές (scenes), δηλαδή συναρτήσεις που αναπαριστούν διαδικαστική γνώση για το συγκεκριμένο σενάριο σε μορφή βημάτων που εκτελούνται σειριακά:
1.entering,
2.movingToWorkingSeat
3.ordering,
4.servicing,
5.billing,
6.paying,
7.exiting.

Τέλος τρέχει ένα συγκεκριμένο στιγμιότυπο του σεναρίου, δηλαδή δύο πελάτες μπαίνουν στο κουρείο και ζηούν συγκεκριμένες υπηρεσίες (scene3) (τα scenes 4-7 εκτελούνται αυτόματα όταν εκτελεστεί το scene3).
Μετά την εκτέλεση ο κόσμος του προγράμματος βρίσκεται σε μια κατάσταση όπου ο κουρέας περιμένει στο γραφείο τον επόμενο πελάτη, έχοντας παράσχει την ζητούμενη υπηρεσία και έχοντας πληρωθεί το αντίτιμο, ο πελάτης στέκεται έξω από το κουρείο φρεσκαρισμένος και κατά τι φτωχότερος, και ο κύκλος είναι έτοιμος να ξανά-αρχίσει. Παράλληλα το πρόγραμμα είναι σε θέση να απαντήσει αν χρησιμοποιήθηκε το τάδε ή το δείνα εργαλείο ή ποιο ήταν το κόστος της υπηρεσίας, ή ο χρόνος που χρειάστηκε.

Παραθέτω τον κώδικα:

;typoi
(define-struct service;parexomeni ipiresia
(name
instruments ;ergaleia poy xreiazontai gia tin ilopoiisi tis ipiresias
cost ;kostos
time) )

(define-struct transaction ;sinalagi
(money ;xrimata
reason ;logos
) )

(define-struct agent
(name
currentPlace ;meros pou vriskete
currentPosition ;Thesi swmatos
nextAction ;Epomeni drasi
nextActionTarget ;Stoxos (agent/place) epomenis drasis
lastAction ;proigoumeni drasi
lastActionTarget ;Stoxos proigoumenis drasis
acceptedAction ;Drasi pou dexthike
acceptedActionSource ;Pigi drasis pou dex8ike
money) ;xrimata
)

(define-struct (server agent) ;eksipiretis
{services} ;ipiresies pou parexei
)

(define-struct (client agent) ;eksipiretoumenos
() )

(define-struct place ;meros
(name places) ;lista me geitonika meri
)

(define-struct (outside place) ;ekswterikos xwros
( ) )

(define-struct (building place) ;ktirio
( ) )

(define-struct (interior place) ;eswterikos xwros
(positionC ;8esi swmatos tou client
positionS ;8esi swmatos tou server
occupied) ;kateilimeno (true/false)
)

;general functions
(define (memberOf item list)

(if (empty? list)
false
(if (equal? (car list) item)
true
(memberOf item (cdr list))
)
)
)

(define (TRANS person placeToGo) ;metafora agent se place
(if (equal? (agent-currentPosition person) "standing")
(if (interior? placeToGo) ;an 8elei na paei se eswteriko xwro
(if (client? person) ;an einai eksipiretoumenos
(if (not (interior-occupied placeToGo)) ;an to meros pou 8elei na paei den einai kateilimeno
(begin
(if (interior? (agent-currentPlace person)) ;an itan se eswteriko xwro
(set-interior-occupied! (agent-currentPlace person) false)
)
(set-agent-currentPlace! person placeToGo) ;pigene sto meros
(set-interior-occupied! placeToGo true) ;kane to occupied=true
)
(begin
(display "Error: TRANS:")
(display (agent-name person))
(display "the place ")
(display (place-name placeToGo))
(display "is occupied ")
(display "\n")
)
)
(begin ;an einai eksipiretis
(set-agent-currentPlace! person placeToGo) ;pigene sto meros
)
)
(begin ;an 8elei na paei se ekswteriko xwro h se ktirio
(if (client? person) ;an einai eksipiretoumenos
(if (interior? (agent-currentPlace person)) ;an itan se eswteriko xwro
(set-interior-occupied! (agent-currentPlace person) false) ;kane ton occupied=false
)
)
(set-agent-currentPlace! person placeToGo) ;pigene sto meros
)
)
(begin
(display "Error: TRANS:")
(display (agent-name person))
(display " is not standing")
(display "\n")
)
)
(display "TRANS: ")
(display (agent-name person))
(display " : ")
(display (place-name (agent-currentPlace person)))
(display "\t")
(display (agent-currentPosition person))
(display "\n")
)

(define (MOVE person positionToTake) ;allagi thesis swmatos
(set-agent-currentPosition! person positionToTake)
(display "MOVE: ")
(display (agent-name person))
(display " : ")
(display (place-name (agent-currentPlace person)))
(display "\t")
(display (agent-currentPosition person))
(display "\n")
)

(define (COMM agent1 actionToPerform agent2) ;epikoinwnia mia drasis pou zita o agent1 na tou efarmosei o agent2
(set-agent-nextAction! agent2 actionToPerform)
(set-agent-nextActionTarget! agent2 agent1)
(display "COMM: ")
(display (agent-name agent1))
(display " to ")
(display (agent-name agent2))
(display " : ")
(if (or (transaction? (agent-nextAction agent2)) (service? (agent-nextAction agent2)))
(begin
(if (service? (agent-nextAction agent2))
(display (service-name (agent-nextAction agent2)))
)
(if (transaction? (agent-nextAction agent2))
(begin
;(display (service-name (transaction-reason (agent-nextAction agent2))))
(display "\t")
(display (transaction-money (agent-nextAction agent2)))
)
)
)
(display (agent-nextAction agent2))
)
(display "\n")
)

(define (EXEC currentAgent) ;ektelesi tou nextAction ston nextActionTarget oi draseis mporei na einai services transactions (draseis me stoxo) h draseis xeris stoxo pou anaparistountai me strings (px waiting leaving)
(display "EXEC: ")
(display (agent-name currentAgent))
(display " : ")
(set-agent-acceptedAction! (agent-nextActionTarget currentAgent) (agent-nextAction currentAgent))
(set-agent-lastAction! currentAgent (agent-nextAction currentAgent))
(set-agent-lastActionTarget! currentAgent (agent-nextActionTarget currentAgent))
(display (agent-lastAction currentAgent))
(if (service? (agent-nextAction currentAgent))
(display (service-name (agent-acceptedAction (agent-nextActionTarget currentAgent))))
)
(if (equal? (agent-nextAction currentAgent) "waiting")
()
)
(if (transaction? (agent-nextAction currentAgent))
(begin
(set-agent-acceptedAction! (agent-nextActionTarget currentAgent) (agent-nextAction currentAgent))
(set-agent-money! (agent-nextActionTarget currentAgent) (+ (agent-money (agent-nextActionTarget currentAgent)) (transaction-money payment)))
(set-agent-money! currentAgent (- (agent-money currentAgent) (transaction-money payment)))
(set-transaction-reason! payment (agent-acceptedAction currentAgent))
(display (service-name (transaction-reason (agent-nextAction currentAgent))))
(display "\t")
(display (transaction-money (agent-nextAction currentAgent)))
)
)
(display "\n")
(set-agent-nextAction! currentAgent "null")
(set-agent-nextActionTarget! currentAgent "null")
)

;To Senario tou Koureiou

;stigmiotipa anaparistoun enoiologiki gnwsi
;ipiresies
(define shave ;ksirisma (make-service "shave" '("foam" "razor" "shavingMachine") 5 10) )

(define hairwash ;lousimo (make-service "hairwash" '("conditioner" "shampoo") 8 15) )

(define haircut ;kourema (make-service "haircut" '("scissors" "shavingMachine") 15 30) )

;sinalages
(define payment ;plirwmi (make-transaction 0 "null") )

;merh
(define desk ;grafeio
(make-interior "Grafeio" '(barbershop) "standing" "null" true) )

(define waitingSeat ;8esi anamonis
(make-interior "Thesi Anamonis" '(barbershop) "sitting" "null" false) )

(define workingSeat ;8esi ergasias
(make-interior "Thesi Ergasias" '(barbershop) "standing" "sitting" false) )

(define barbershop ;koureio
(make-building "Koureio" '(desk waitingSeat workinSeat outsidePlace)) )

(define outsidePlace ;eksw
(make-outside "Eksw" '(barbershop)) )

;agents
(define customer ;pelatis
(make-client "Kwstas" outsidePlace "standing" "entering" barbershop "null" "null" "null" "null" 20) )

(define customer2 ;pelatis
(make-client "giwrgos" outsidePlace "standing" "entering" barbershop "null" "null" "null" "null" 30) )

(define barber ;koureas
(make-server "Aggelos" desk "standing" "waiting" "null" "null" "null" "null" "null" 20 '(shave hairwash haircut)) )

;skines anaparistoun diadikastiki gnwsi
;Scene 1: Entering
(define (entering C barbershop)
(display "entering")
(display "\n")
(TRANS C barbershop)
(if (not (interior-occupied workingSeat)) ;an einai adeia i 8esi ergasias
(begin
(TRANS C workingSeat) ;pigene ekei
(MOVE C "sitting") ;katse
(set-agent-nextAction! C "null") ;oloklirwses tin drasi kai den exeis epomeni
(set-agent-nextActionTarget! C "null")
)
(if (not (interior-occupied waitingSeat)) ;alliws an einai adeia i 8esi anamonis
(begin
(TRANS C waitingSeat) ;pigene
(MOVE C "sitting") ;katse
(set-agent-nextAction! C "waiting") ;nea drasi: perimene
(set-agent-nextActionTarget! C "null") ;drasi xwris stoxo
)
)
)
)

;Scene 3: Ordering
(define (ordering C S servic) ;paragelia mias service apo ton server
(display "ordering")
(display "\n")
(TRANS S workingSeat) ;o server pigenei sti 8esi ergasias
(COMM C servic S) ;o client zita tin ipiresia
(servicing C S servic) ;epomeno scene
)

;Scene 4: Servicing
(define (servicing C S servic) ;paroxi tis ipiresias
(display "servicing")
(display "\n")
(EXEC S) ;ektelesi tis nextAction tou server (pou einai i service pou ziti8ike apo ton client sto proigoumeno scene)
(billing C S servic) ;epomeno scene
)

;Scene 5: Billing
(define (billing C S servic) ;xrewsi
(display "billing")
(display "\n")
(set-transaction-money! payment (service-cost servic)) ;xrewsi oso to kostos tis parexomenis ipiresias
(set-transaction-reason! payment (service-name servic))
(COMM S payment C) ;o server zita drasi tipou transaction apo ton client
(paying C S servic) ;epomeno scene
)

;Scene 6: Paying
(define (paying C S servic) ;eksoflisi
(display "paying")
(display "\n")
(MOVE C "standing") ;o pelatis se or8ia 8esi
(TRANS C barbershop) ;apomakrinete apo ti 8esi ergasias
(EXEC C) ;ektelei tin drasi tou (pou einai transaction apo to proigoumeno scene)
(TRANS S desk) ;o server paei sto grafeio gia na 3anaarxisei o kiklos
(set-agent-nextAction! S "waiting")
(exiting C) ;epomeno scene
)

(define (exiting C) ;o pelatis feygei
(display "leaving")
(display "\n")
(TRANS C outsidePlace)
(set-agent-nextAction! C "leaving")
(set-agent-nextActionTarget! C "null")
(if (interior-occupied waitingSeat)
(movingToWorkingSeat customer2)
)
)

(define (movingToWorkingSeat C) ;metafora apo 8esi ergasias se 8esi anamonis
(display "moving to working seat")
(display "\n")
(MOVE C "standing")
(if (not (interior-occupied workingSeat)) ;an einai adeia i 8esi ergasias
(begin
(TRANS C workingSeat) ;pigene ekei
(MOVE C "sitting") ;katse
(set-agent-nextAction! C "null") ;oloklirwses tin drasi kai den exeis epomeni
(set-agent-nextActionTarget! C "null")
(ordering customer2 barber haircut)
)
(if (not (interior-occupied waitingSeat)) ;alliws an einai adeia i 8esi anamonis
(begin
(TRANS C waitingSeat) ;pigene
(MOVE C "sitting") ;katse
(set-agent-nextAction! C "waiting") ;nea drasi: perimene
(set-agent-nextActionTarget! C "null") ;drasi xwris stoxo
)
)
)
)

(begin
(display "arxiki katastasi")
(display "\n")
(display (agent-name customer))
(display " : ")
(display (place-name (agent-currentPlace customer)))
(display "\t")
(display (agent-nextAction customer))
(display "\n")
(display (agent-name customer2))
(display " : ")
(display (place-name (agent-currentPlace customer2)))
(display "\t")
(display (agent-nextAction customer2))
(display "\n")
(entering customer barbershop)
(entering customer2 barbershop)
(if (equal? (agent-currentPlace customer) workingSeat)

(begin
(ordering customer barber hairwash)
)
(exiting customer)
)
)


Μετά την εκτέλεση το πρόγραμμα εκτυπώνει τα παρακάτω :

Welcome to DrScheme, version 4.1 [3m].Language: Pretty Big; memory limit: 128 megabytes.
arxiki katastasi
Kwstas : Eksw entering
giwrgos : Eksw entering
entering
TRANS: Kwstas : Koureio standing
TRANS: Kwstas : Thesi Ergasias standing
MOVE: Kwstas : Thesi Ergasias sitting
entering
TRANS: giwrgos : Koureio standing
TRANS: giwrgos : Thesi Anamonis standing
MOVE: giwrgos : Thesi Anamonis sitting
ordering
TRANS: Aggelos : Thesi Ergasias standing
COMM: Kwstas to Aggelos : hairwash
servicing
EXEC: Aggelos : #hairwash
billing
COMM: Aggelos to Kwstas : 8
paying
MOVE: Kwstas : Thesi Ergasias standing
TRANS: Kwstas : Koureio standing
EXEC: Kwstas : #hairwash 8
TRANS: Aggelos : Grafeio standing
leaving
TRANS: Kwstas : Eksw standing
moving to working seat
MOVE: giwrgos : Thesi Anamonis standing
TRANS: giwrgos : Thesi Ergasias standing
MOVE: giwrgos : Thesi Ergasias sitting
ordering
TRANS: Aggelos : Thesi Ergasias standing
COMM: giwrgos to Aggelos : haircut
servicing
EXEC: Aggelos : #haircut
billing
COMM: Aggelos to giwrgos : 15
paying
MOVE: giwrgos : Thesi Ergasias standing
TRANS: giwrgos : Koureio standing
EXEC: giwrgos : #haircut 15
TRANS: Aggelos : Grafeio standing
leaving
TRANS: giwrgos : Eksw standing>

Επιπλέον το πρόγραμμα μπορεί να απαντήσει σε μια σειρά από ερωτήσεις του τύπου :

(agent-money barber) πόσα χρήματα έχει ο κουρέας
(agent-lastActionTarget barber) ποιά ήταν η τελευταία δράση του κουρέα
(agent-name (agent-lastActionTarget barber)) ποιος ήταν ο στόχος της τελευταίας δράσης του κουρέα
(agent-currentPlace customer) που βρίσκεται τώρα ο 1ος πελάτης
(place-name (agent-currentPlace customer)) ποιο το όνομα του μέρους που βρίσκεται τώρα ο 1ος πελάτης
(agent-nextAction customer)
(agent-lastAction customer)
(transaction-reason (agent-lastAction customer))
(service name (transaction-reason (agent-lastAction customer)))
(transaction-money (agent-lastAction customer))
(agent-money customer)
(agent-lastActionTarget customer)
(agent-name (agent-lastActionTarget customer))

Δεν υπάρχουν σχόλια: