#+title: 💀 OOΠin Prolog 💀
-#+author: Bizzoni Leonardo (899629),
-#+author: Kier Mirko Tolentino(899728),
+#+author: Bizzoni Leonardo (899629)
+#+author: Kier Mirko Tolentino(899728)
#+author: Barone Matteo(894594)
#+options: TOC:nil
#+end_src
** Sostituzione del termine `this`
-
-Predicato che viene usato per sostituire 'this' con la vera istanza
-utilizzata (<Result>).
+Predicato utilizzato per sostituire l'atomo /this/ con la vera istanza.
+Dato un predicato /Body/ questo viene separato nei suoi termini costituenti
+e (/funtore e argomenti/) *per ogni* argomento richiama la /replace/.
+In questo modo possiamo cercare l'atomo da sostituire anche all'interno di
+termini composti come chimate di funzioni.
#+begin_src prolog :tangle oop.pl
replace(OldTerm, NewTerm, Body, NewTerm) :- Body == OldTerm, !.
#+end_src
** Controllo dei tipi
+Per i tipi implementati da Prolog si tratta di semplici predicati di
+controllo sul valore passato.
-Si definiscono i controlli dei tipi e delle classi con /type_check/.
-Sono tutti dei semplici metodi di controllo, se la variabile è del tipo corrento viene restitituo true.
+Se invece il tipo passato è un atomo rappresentante una classe allora si
+tratta di verificare che il valore sia un'istanza di quella classe o una
+sua classe figlio andando quindi ad esplorare la gerarchia della classi.
#+begin_src prolog :tangle oop.pl
type_check(_X, nil) :- !.
** Definizione di una classe
*** Effettivo predicato `def_class`
-
-Defininiamo la classe, controllando che essa già non sia presente nella base di conoscenza ed
-ereditiamo, se esistenti, field da una classe genitore.
+La definizione di una classe richiede che `classname` non sia già il nome
+di una classe pre-esistente nella base di conoscenza.
+Una volta effettuato questo controllo possiamo ereditare tutti
+i field ed i metodi dalle classi genitore se presenti e creare relazioni
+tra le /parts/ della classe da creare ed il nome della classe stessa grazie
+al predicato /add_part/.
#+begin_src prolog :tangle oop.pl
wrapped_def_class(ClassName, Parents, Parts) :-
add_part(ClassName, Parts).
#+end_src
-*** Ereditazione di field da superclass
+*** Ereditazione di /parts/ da superclassi
+Viene svolto inizialmente lo stesso controllo del [[*Effettivo predicato `def_class`][predicato precedente]]
+con l'aggiunta del controllo sul primo genitore nella lista di genitori.
+Se questo non è una classe allora non possiamo ereditare niente!
-Metodo che permette di ereditare i campi dal genitore,
-dopo aver verificato la presenza di una classe /Parent/,
-si cercano i method del genitore e si aggiungono alla sottoclasse.
+Dopo di chè creiamo una relazione tra il genitore e la classe figlio
+che creerà una gerarchia di classi utile nel [[*Controllo dei tipi][controllo dei tipi]].
#+begin_src prolog :tangle oop.pl
set_superclass(_ClassName, []) :- !.
** Istanziazione di una classe
*** Effettivo predicato `make`
+Dato un atomo per /InstanceName/ possiamo procedere alla creazione
+di un'istanza creando una relazione tra quest'atomo
+ed il nome della classe.
+
+Per evitare di sovrascrivere i field della classe figlio per prima cosa
+creaiamo relazioni tra i field membri delle superclassi e solo dopo
+quelli della classe stessa.
-Si crea l'effetiva classe, controllando i parametri d'ingrsso e inserendo i campi della classe.
-Sia passati in ingresso che quelli ereditati da un eventuale genitore.
+In questo modo l'atomo /InstanceName/ è in relazione con tutti field della
+classe e dei genitori.
+Se la classe effettua /l'override/ di un field allora il valore di quel
+field nell'istanza sarà proprio quello della classe e non il valore del
+genitore.
#+begin_src prolog :tangle oop.pl
wrapped_make(InstanceName, ClassName, Fields) :-
#+end_src
*** Assegnamento dei valori ereditati dalla superclass all'istanza
-
-Vengono trovati e assegnati i field alla classe figlio.
+Dato che field e metodi di una superclasse vengono già ereditati durante
+la creazione della classe basta semplicemente trovare tutti i field
+e creare relazioni tra questi ultimi e l'atomo /InstanceName/.
#+begin_src prolog :tangle oop.pl
instanciate_superclass(InstanceName, ClassName) :-
#+end_src
** Ricerca di un'istanza
-
-Metodo per cercare un'istanza.
-SI verifica che esista l'istanza e si controlla ricorsivamente la lista dei campi,
-se l'istanza non ha field allora si controlla solo l'esistenza dell'istanza.
+Se non viene passato un atomo al predicato [[*make][make]] ma bensì una variabile
+allora cerchiamo nella base di conoscenza un qualche atomo in relazione
+con il nome di classe dato.
+
+Inoltre se vengono passati dei /field/ controlliamo che /InstanceName/ (/che nel
+frattempo avrà unificato con un atomo in relazione con classname/) sia in
+relazione con il nome ed il valore del /field/.
+Se non lo fosse allora grazie al /backtracking/ vengono esplorate le altre
+alternative.
#+begin_src prolog :tangle oop.pl
search_instance(InstanceName, ClassName, [=(Field,Value) | Other]) :-