;Soluzione di Mapelli I. e Cornaz M. ;Soluzione del Mondo dei blocchi deterministica (non c'é backtracking). ;Il primo passo é individuare i blocchi che si trovano giá nella posizione finale, ;vengono elencati anche i blocchi da spostare. Vengono privilegiate le azioni sui ;blocchi che possono essere inseriti nella posizione finale. Un blocco che non é in ;posizione corretta viene posto sul tavolo. Dopo ogni mossa andiamo ad aggiornare ;l'elenco dei blocchi da spostare e di quelli corretti. (defmodule MAIN (export ?ALL)) (deffacts stato_iniziale (status clear k NA) (status on k a) (status on a b) (status ontable b NA) (status clear l NA) (status on l d) (status on d c) (status ontable c NA) (status clear e NA) (status on e f) (status on f g) (status ontable g NA) (status clear j NA) (status on j i) (status on i h) (status ontable h NA) (status clear o NA) (status on o n) (status on n m) (status ontable m NA) (status clear z NA) (status on z v) (status on v u) (status on u t) (status on t s) (status on s r) (status on r q) (status on q p) (status ontable p NA)) (deffacts stato_finale (goal clear l NA) (goal on l k) (goal on k a) (goal ontable a NA) (goal clear z NA) (goal on z u) (goal on u b) (goal on b c) (goal ontable c NA) (goal clear m NA) (goal on m e) (goal on e d) (goal ontable d NA) (goal clear j NA) (goal on j g) (goal on g f) (goal ontable f NA) (goal clear p NA) (goal on p i) (goal on i h) (goal ontable h NA) (goal clear v NA) (goal on v o) (goal on o n) (goal ontable n NA) (goal clear t NA) (goal on t s) (goal on s r) (goal on r q) (goal ontable q NA)) (deffacts passo (controllo_goal)) ;controllo dello stato finale, se non lo raggiungiamo asseriamo un fatto continua e rimuovendo il fatto ;controllo_goal (defrule controllo_stato_finale (declare (salience 100)) ?f<-(controllo_goal) (goal ?op ?x ?y) (not (status ?op ?x ?y)) => (retract ?f) (assert (continua))) ;se il fatto controllo_goal non é stato rimosso, allora abbiamo trovato la soluzione e ci fermiamo (defrule soluzione_trovata (controllo_goal) => (assert (soluzione_trovata)) (halt)) ;regola che viene richiamata solo una volta all'inizio, richiama il modulo ELENCA_BLOCCHI ;che ci dirá quali blocchi sono in posizione corretta e quali possono essere spostati (defrule selezione_blocchi (continua) (not(numero_mosse ?)) => (assert(numero_mosse 0)) (focus ELENCA_BLOCCHI)) ;ad ogni passo possiamo effettuare piú spostamenti, al modulo SCEGLI_BLOCCO deleghiamo la scelta ;del blocco da spostare (defrule scelta_blocco ?f<-(continua) (numero_mosse ?) => (focus SCEGLI_BLOCCO) (retract ?f)) ;Mettiamo un blocco sul tavolo nella posizione finale corretta (defrule puttable_and_goal ?f1<-(esegui goal ontable ?x ) ?f2<-(status on ?x ?y) ?f3<-(numero_mosse ?n) ?f4<-(prendi_colonna ?x) => (retract ?f1 ?f2 ?f3 ?f4) (assert (status ontable ?x NA)) (assert (status clear ?y NA)) (assert (blocco_corretto ?x)) (assert (controlla ?y)) (assert (numero_mosse (+ ?n 1)))) ;Mettiamo un blocco sul tavolo ma la sua posizione non é quella corretta (defrule puttable_and_not_goal ?f1<-(esegui ontable ?x ) ?f2<-(status on ?x ?y) ?f3<-(numero_mosse ?n) => (retract ?f1 ?f2 ?f3) (assert (status ontable ?x NA)) (assert (status clear ?y NA)) (assert (controlla ?y)) (assert (numero_mosse (+ ?n 1)))) ;Prendiamo un blocco dal tavolo e lo inseriamo nella sua posizione corretta (su altri blocchi) (defrule put1 ?f1<-(esegui goal on ?x ?y) ?f2<-(status ontable ?x NA) ?f3<-(status clear ?y NA) ?f4<-(numero_mosse ?n) ?f5<-(prendi_colonna ?x) => (retract ?f1 ?f2 ?f3 ?f4 ?f5) (assert (status on ?x ?y)) (assert (blocco_corretto ?x)) (assert (controllo_goal)) (assert (numero_mosse (+ ?n 1)))) ;Prendiamo un blocco che non é sul tavolo e lo inseriamo nella sua posizione corretta (su altri blocchi) (defrule put2 ?f1<-(esegui goal on ?x ?y) ?f2<-(status on ?x ?z) ?f3<-(status clear ?y NA) ?f4<-(numero_mosse ?n) ?f5<-(prendi_colonna ?x) => (retract ?f1 ?f2 ?f3 ?f4 ?f5) (assert (status on ?x ?y)) (assert (status clear ?z NA)) (assert (blocco_corretto ?x)) (assert (controlla ?z)) (assert (numero_mosse (+ ?n 1)))) ;Dopo aver fatto uno spostamento, andiamo ad aggiornare i blocchi corretti e gli eventuali nuovi ;blocchi che si possono spostare (defrule aggiorna_elenco (not(controllo_goal)) ?f<-(controlla ?x) (status on ?x ?y) (blocco_corretto ?y) (goal on ?x ?y) => (assert(blocco_corretto ?x)) (assert(controllo_goal)) (retract ?f)) (defrule aggiorna_elenco2 (not(controllo_goal)) ?f<-(controlla ?x) (status on ?x ?y) (not(blocco_corretto ?y)) => (assert(prendi_colonna ?x)) (assert(controllo_goal)) (retract ?f)) (defrule aggiorna_elenco3 (not(controllo_goal)) ?f<-(controlla ?x) (status on ?x ?y) (blocco_corretto ?y) (not(goal on ?x ?y)) => (assert(prendi_colonna ?x)) (assert(controllo_goal)) (retract ?f)) (defrule aggiorna_elenco4 (not(controllo_goal)) ?f<-(controlla ?x) (status ontable ?x NA) (not(blocco_corretto ?x)) => (assert(prendi_colonna ?x)) (assert(controllo_goal)) (retract ?f)) (defrule aggiorna_elenco5 (not(controllo_goal)) ?f<-(controlla ?x) (blocco_corretto ?x) => (retract ?f) (assert(controllo_goal))) (defmodule ELENCA_BLOCCHI (export ?ALL)(import MAIN ?ALL)) (defrule base_colonna_diversa (declare (salience 100)) (status ontable ?y NA) (not (goal ontable ?y NA)) (numero_mosse ?) => (assert(prendi_colonna ?y))) (defrule base_colonna_uguale (declare (salience 100)) (status ontable ?y NA) (goal ontable ?y NA) (numero_mosse ?) => (assert(controlla_colonna ?y)) (assert(blocco_corretto ?y))) (defrule colonna_diversa (declare (salience 100)) ?f<-(prendi_colonna ?y) (status on ?z ?y) (numero_mosse ?) => (retract ?f) (assert (prendi_colonna ?z))) (defrule colonna_uguale (declare (salience 100)) ?f<-(controlla_colonna ?y) (status on ?z ?y) (goal on ?z ?y) (numero_mosse ?) => (retract ?f) (assert (controlla_colonna ?z)) (assert (blocco_corretto ?z))) (defrule colonna_uguale_diversa (declare (salience 100)) ?f<-(controlla_colonna ?y) (status on ?z ?y) (not (goal on ?z ?y)) (numero_mosse ?) => (retract ?f) (assert (prendi_colonna ?z))) (defrule cancella_controlla_colonna (declare (salience 10)) ?f<-(controlla_colonna ?) => (retract ?f)) (defrule fine_elenco (declare (salience 1)) (numero_mosse ?) => (pop-focus)) (defmodule SCEGLI_BLOCCO (import ELENCA_BLOCCHI ?ALL)(export ?ALL)) (defrule inizio (not (inizio_scelta)) (not (fine_scelta)) => (assert(inizio_scelta))) (defrule scelta_ontable ?f<-(inizio_scelta) (prendi_colonna ?x) (not(status ontable ?x NA)) (goal ontable ?x NA) (numero_mosse ?) => (assert(esegui goal ontable ?x)) (retract ?f) (assert (fine_scelta))) (defrule scelta_on ?f<-(inizio_scelta) (prendi_colonna ?x) (blocco_corretto ?y) (goal on ?x ?y) (status clear ?y NA) (numero_mosse ?) => (assert(esegui goal on ?x ?y)) (retract ?f) (assert (fine_scelta))) (defrule scelta_ontable2 (declare (salience -1)) ?f<-(inizio_scelta) (prendi_colonna ?x) (not(status ontable ?x NA)) (numero_mosse ?) => (assert(esegui ontable ?x)) (retract ?f) (assert (fine_scelta))) (defrule esci ?f<-(fine_scelta) => (retract ?f) (pop-focus))