From f25f2168723e479bfbca400131c11011200d145b Mon Sep 17 00:00:00 2001 From: LeonardoBizzoni Date: Tue, 9 Jan 2024 08:55:08 +0100 Subject: [PATCH] L'ultima modifica faceva merda --- Prolog/README.org | 70 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 22 deletions(-) diff --git a/Prolog/README.org b/Prolog/README.org index 4b9acd8..ce52d9e 100644 --- a/Prolog/README.org +++ b/Prolog/README.org @@ -1,6 +1,6 @@ #+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 @@ -417,9 +417,11 @@ set_fields(InstanceName, _ClassName, _Fields) :- #+end_src ** Sostituzione del termine `this` - -Predicato che viene usato per sostituire 'this' con la vera istanza -utilizzata (). +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, !. @@ -437,9 +439,12 @@ replace(OldTerm, NewTerm, Body, Result) :- #+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) :- !. @@ -474,9 +479,12 @@ type_check(ClassName, Instance) :- ** 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) :- @@ -490,11 +498,13 @@ 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, []) :- !. @@ -517,9 +527,19 @@ set_superclass(ClassName, [Parent | OtherParents]) :- ** 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) :- @@ -537,8 +557,9 @@ 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) :- @@ -553,10 +574,15 @@ 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]) :- -- 2.52.0