]> git.leonardobizzoni.com Git - ObjectOriented-Prolog-Lisp/commitdiff
Aggiunti commenti al codice prolog
authorLeonardoBizzoni <leo2002714@gmail.com>
Sat, 30 Dec 2023 10:47:30 +0000 (11:47 +0100)
committerLeonardoBizzoni <leo2002714@gmail.com>
Sat, 30 Dec 2023 10:47:30 +0000 (11:47 +0100)
Prolog/README.org
Prolog/oop.pl

index fded3598767bbbefc516dcd9ba6c1f5339574db2..8c0b1f8c41a8667f69fb85954ddd0a4dd8e65a7d 100644 (file)
@@ -35,6 +35,9 @@ def_class(ClassName, Parents, Parts) :-
     is_list(Parents),
     is_list(Parts),
     \+ wrapped_def_class(ClassName, Parents, Parts),
+
+    %% Se fallisce la definizione della classe
+    %% elimina le informazioni residue dalla base di conoscenza
     retractall(is_class(ClassName)),
     retractall(is_class(ClassName, _)),
     retractall(is_child_of(_, ClassName)),
@@ -131,36 +134,34 @@ Descrivi un costruttore di Java.
 *** Implementazione
 #+begin_src prolog :tangle oop.pl
 make(InstanceName, ClassName) :-
-    var(InstanceName),
-    nonvar(ClassName),
-    is_class(ClassName),
-    !,
-    search_instance(InstanceName, ClassName, []).
+    make(InstanceName, ClassName, []).
 
-make(InstanceName, ClassName) :-
-    atom(InstanceName),
+make(InstanceName, ClassName, Fields) :-
+    var(InstanceName),
     nonvar(ClassName),
     is_class(ClassName),
     !,
-    make(InstanceName, ClassName, []).
+    search_instance(InstanceName, ClassName, Fields).
 
 make(InstanceName, ClassName, Fields) :-
+    atom(InstanceName),
     nonvar(InstanceName),
+    is_class(ClassName),
     wrapped_make(InstanceName, ClassName, Fields),
     !.
 
 make(InstanceName, ClassName, Fields) :-
+    atom(InstanceName),
     nonvar(InstanceName),
+    is_class(ClassName),
     \+ wrapped_make(InstanceName, ClassName, Fields),
-    !,
+
+    %% Se fallisce la definizione dell'instance
+    %% elimina le informazioni residue dalla base di conoscenza
     retractall(is_instance(InstanceName)),
     retractall(is_instance(InstanceName, _)),
     retractall(field(InstanceName, _, _)),
     fail().
-
-make(InstanceName, ClassName, Fields) :-
-    var(InstanceName),
-    search_instance(InstanceName, ClassName, Fields).
 #+end_src
 
 *** Esempio pratico
@@ -174,6 +175,7 @@ make(root, node, [value = 200]).                  %% true.
 make(Instance, foobar).            %% Instance = fb.
 make(Instance, bar, [bar = "69"]). %% Instance = b; false.
 #+end_src
+
 ** field
 *** Definizione
 Estrae il valore di una classe da un campo
@@ -220,6 +222,24 @@ fieldx(Instance, [FieldName | Others], Res) :-
 fieldx(fb, [foo,bar,foobar], Result).
 #+end_src
 
+** inst
+*** Definizione
+Dato un oggetto che rappresenta un'istanza restituisce il nome dell'istanza.
+Si nella nostra implementazione è banale perchè l'oggetto che rappresenta l'istanza è il nome dell'istanza.
+
+*** Implementazione
+#+begin_src prolog :tangle oop.pl
+inst(InstanceName, InstanceName).
+#+end_src
+
+*** Esempio pratico
+#+begin_src prolog
+inst(f, f).     %% true.
+inst(b, b).     %% true.
+inst(X, fb).    %% X = fb.
+inst(fb, root). %% false.
+#+end_src
+
 * Predicati helper
 ** Predicati dinamici
 Predicati usati con `assert` guarda dove vengono usati e scrivi 2 righe.
@@ -247,7 +267,12 @@ add_part(ClassName, [field(Name, Value) | OtherParts]) :-
       is_class(ClassName),
       is_member(field(Name, _, _), ClassName),
       !,
+
+      %% Se il field da aggiungere è anche un field di una superclass
+      %% allora rimuovilo della base di conoscenza
       retractall(is_member(field(Name, _, _), ClassName)),
+
+      %% e sostituiscilo con il field della classe stessa
       asserta(is_member((field(Name, Value, nil)), ClassName)),
       add_part(ClassName, OtherParts).
 
@@ -255,6 +280,9 @@ add_part(ClassName, [field(Name, Value) | OtherParts]) :-
       is_class(ClassName),
       \+ is_member(field(Name, _, _), ClassName),
       !,
+
+      %% Se il field non è anche un field di una superclass
+      %% allora di che è un field di questa classe
       asserta(is_member((field(Name, Value, nil)), ClassName)),
       add_part(ClassName, OtherParts).
 #+end_src
@@ -266,8 +294,15 @@ add_part(ClassName, [field(Name, Value, Type) | OtherParts]) :-
       is_class(ClassName),
       is_member(field(Name, _, _), ClassName),
       !,
+
+      %% Se il field da aggiungere è anche un field di una superclass
+      %% allora rimuovilo della base di conoscenza
       retractall(is_member(field(Name, _, _), ClassName)),
+
+      %% Controlla che il valore del field sia del tipo del field
       type_check(Type, Value),
+
+      %% e sostituiscilo con il field della classe stessa
       asserta(is_member(field(Name, Value, Type), ClassName)),
       add_part(ClassName, OtherParts).
 
@@ -275,8 +310,11 @@ add_part(ClassName, [field(Name, Value, Type) | OtherParts]) :-
       is_class(ClassName),
       \+ is_member(field(Name, _, _), ClassName),
       !,
-      retractall(is_member(field(Name, _, _), ClassName)),
+
+      %% Se il field non è anche un field di una superclass
+      %% controlla che il valore del field sia del tipo del field
       type_check(Type, Value),
+      %% e di che è un field di questa classe
       asserta(is_member(field(Name, Value, Type), ClassName)),
       add_part(ClassName, OtherParts).
 #+end_src
@@ -289,8 +327,11 @@ add_part(ClassName, [method(Name, ArgList, Body) | OtherParts]) :-
       is_list(ArgList),
       is_class(ClassName),
       asserta(is_member(method(Name, ArgList, Body), ClassName)),
+
+      %% Ricava il termine composto che rappresenta la testa del predicato
       Head =.. [Name, InstanceName | ArgList],
       !,
+
       replace(this, InstanceName, Body, NewBody),
       asserta(Head :- (is_instance(InstanceName, ClassName), NewBody, !)),
       add_part(ClassName, OtherParts).
@@ -304,7 +345,9 @@ set_superclass_fields(_InstanceName, _ClassName, []) :- !.
 set_superclass_fields(InstanceName,
               ClassName,
               [[Name, Value, Type] | OtherFields]) :-
+    %% Controlla che il valore sia del tipo corretto
     type_check(Type, Value),
+
     assertz(field(InstanceName, Name, Value)),
     set_superclass_fields(InstanceName, ClassName, OtherFields).
 #+end_src
@@ -317,38 +360,48 @@ set_fields(_InstanceName, _ClassName, []) :- !.
 set_fields(InstanceName,
               ClassName,
               [=(Name, Value) | OtherFields]) :-
+    %% Controlla che `Name` sia un field dell'istanza
     field(InstanceName, Name, OldValue),
+    %% ed un membro della classe
     is_member(field(Name, _Value, Type), ClassName),
+
+    %% Controlla che il nuovo valore sia del tipo corretto
     type_check(Type, Value),
-    retractall(field(InstanceName, Name, OldValue)),
     !,
+
+    %% Rimuove della base di conoscenza il vecchio field
+    retractall(field(InstanceName, Name, OldValue)),
+    %% e lo aggiorna con il nuovo valore
     asserta(field(InstanceName, Name, Value)),
+
     set_fields(InstanceName, ClassName, OtherFields).
 
+%% Se arriva a questo caso si è verificato un errore
+%% e deve eliminare le informazioni residue
+%% della creazione dell'istanza
 set_fields(InstanceName, _ClassName, _Fields) :-
     retractall(is_instance(InstanceName)),
     retractall(is_instance(InstanceName, _)),
     retractall(field(InstanceName, _, _)),
-    !,
     fail().
 #+end_src
 
-** Sostituzione di termine
+** Sostituzione del termine `this`
 Magia nera chiedi a Mirko.
 
 #+begin_src prolog :tangle oop.pl
-replace(Subterm0, Subterm, Term0, Term) :-
-       Term0 == Subterm0,
-       !,
-       Term = Subterm.
-replace(_Subterm0, _Subterm, Term0, Term) :-
-       var(Term0),
-       !,
-       Term = Term0.
-replace(Subterm0, Subterm, Term0, Term) :-
-       Term0 =.. [F | Args0],
-       maplist(replace(Subterm0,Subterm), Args0, Args),
-       Term =.. [F | Args].
+replace(OldTerm, NewTerm, Body, NewTerm) :- Body == OldTerm, !.
+replace(_OldTerm, _NewTerm, Body, Body) :- var(Body), !.
+replace(OldTerm, NewTerm, Body, Result) :-
+       Body =.. [Funct | BodyFunctArgs],
+
+       %% Chiama ricorsivamente `replace` sugli argomenti di `Body`
+       maplist(replace(OldTerm,NewTerm), BodyFunctArgs, NewFunctArgs),
+
+       %% Ricostruisci il termine composto con:
+       %% - stesso funtore di `Body`
+       %% - argomenti a cui è stata applicata la `replace`
+       Result =.. [Funct | NewFunctArgs].
 #+end_src
 
 ** Controllo dei tipi
@@ -409,6 +462,8 @@ set_superclass(ClassName, [Parent | OtherParents]) :-
     asserta(is_child_of(Parent, ClassName)),
     def_class(ClassName, OtherParents),
 
+    %% Trova tutti i field/method del genitore
+    %% e aggiungili alla classe figlio
     findall(Part,
            is_member(Part, Parent),
            ParentParts),
@@ -420,25 +475,28 @@ set_superclass(ClassName, [Parent | OtherParents]) :-
 #+begin_src prolog :tangle oop.pl
 wrapped_make(InstanceName, ClassName, Fields) :-
     is_list(Fields),
-    !,
-    instanciate_superclass(InstanceName, ClassName),
-    set_fields(InstanceName, ClassName, Fields).
-#+end_src
-
-*** Assegnamento dei valori ereditati dalla superclass all'istanza
-#+begin_src prolog :tangle oop.pl
-instanciate_superclass(InstanceName, ClassName) :-
     atom(InstanceName),
     nonvar(ClassName),
     is_class(ClassName),
     \+ is_instance(InstanceName),
-    !,
+
     asserta(is_instance(InstanceName)),
     asserta(is_instance(InstanceName, ClassName)),
 
+    instanciate_superclass(InstanceName, ClassName),
+    set_fields(InstanceName, ClassName, Fields).
+#+end_src
+
+*** Assegnamento dei valori ereditati dalla superclass all'istanza
+#+begin_src prolog :tangle oop.pl
+instanciate_superclass(InstanceName, ClassName) :-
+    %% Trova tutti i field della classe da istanziare
+    %% e raggruppali in terne (nome, valore, tipo)
     findall([Name, Value, Type],
            is_member(field(Name, Value, Type), ClassName),
            Fields),
+
+    %% Dì per ogni field che è `field` dell'instance `InstanceName`
     set_superclass_fields(InstanceName, ClassName, Fields).
 #+end_src
 
index 1d005902af8fd4454088ae971bd760a818af4eaa..b63a1f414ec663f3376cddc248398b429b2fc575 100644 (file)
@@ -14,6 +14,9 @@ def_class(ClassName, Parents, Parts) :-
     is_list(Parents),
     is_list(Parts),
     \+ wrapped_def_class(ClassName, Parents, Parts),
+
+    %% Se fallisce la definizione della classe
+    %% elimina le informazioni residue dalla base di conoscenza
     retractall(is_class(ClassName)),
     retractall(is_class(ClassName, _)),
     retractall(is_child_of(_, ClassName)),
@@ -21,37 +24,35 @@ def_class(ClassName, Parents, Parts) :-
     fail().
 
 make(InstanceName, ClassName) :-
-    var(InstanceName),
-    nonvar(ClassName),
-    is_class(ClassName),
-    !,
-    search_instance(InstanceName, ClassName, []).
+    make(InstanceName, ClassName, []).
 
-make(InstanceName, ClassName) :-
-    atom(InstanceName),
+make(InstanceName, ClassName, Fields) :-
+    var(InstanceName),
     nonvar(ClassName),
     is_class(ClassName),
     !,
-    make(InstanceName, ClassName, []).
+    search_instance(InstanceName, ClassName, Fields).
 
 make(InstanceName, ClassName, Fields) :-
+    atom(InstanceName),
     nonvar(InstanceName),
+    is_class(ClassName),
     wrapped_make(InstanceName, ClassName, Fields),
     !.
 
 make(InstanceName, ClassName, Fields) :-
+    atom(InstanceName),
     nonvar(InstanceName),
+    is_class(ClassName),
     \+ wrapped_make(InstanceName, ClassName, Fields),
-    !,
+
+    %% Se fallisce la definizione dell'instance
+    %% elimina le informazioni residue dalla base di conoscenza
     retractall(is_instance(InstanceName)),
     retractall(is_instance(InstanceName, _)),
     retractall(field(InstanceName, _, _)),
     fail().
 
-make(InstanceName, ClassName, Fields) :-
-    var(InstanceName),
-    search_instance(InstanceName, ClassName, Fields).
-
 :- dynamic field/3.
 
 fieldx(Instance, [FieldName], Res) :-
@@ -62,6 +63,8 @@ fieldx(Instance, [FieldName | Others], Res) :-
     field(Instance, FieldName, _Value),
     fieldx(Instance, Others, Res).
 
+inst(InstanceName, InstanceName).
+
 :- dynamic is_class/1.
 :- dynamic is_child_of/2.
 :- dynamic is_member/2.
@@ -69,11 +72,17 @@ fieldx(Instance, [FieldName | Others], Res) :-
 :- dynamic is_instance/2.
 
 add_part(ClassName, []) :- is_class(ClassName), !.
+
 add_part(ClassName, [field(Name, Value) | OtherParts]) :-
       is_class(ClassName),
       is_member(field(Name, _, _), ClassName),
       !,
+
+      %% Se il field da aggiungere è anche un field di una superclass
+      %% allora rimuovilo della base di conoscenza
       retractall(is_member(field(Name, _, _), ClassName)),
+
+      %% e sostituiscilo con il field della classe stessa
       asserta(is_member((field(Name, Value, nil)), ClassName)),
       add_part(ClassName, OtherParts).
 
@@ -81,6 +90,9 @@ add_part(ClassName, [field(Name, Value) | OtherParts]) :-
       is_class(ClassName),
       \+ is_member(field(Name, _, _), ClassName),
       !,
+
+      %% Se il field non è anche un field di una superclass
+      %% allora di che è un field di questa classe
       asserta(is_member((field(Name, Value, nil)), ClassName)),
       add_part(ClassName, OtherParts).
 
@@ -88,8 +100,15 @@ add_part(ClassName, [field(Name, Value, Type) | OtherParts]) :-
       is_class(ClassName),
       is_member(field(Name, _, _), ClassName),
       !,
+
+      %% Se il field da aggiungere è anche un field di una superclass
+      %% allora rimuovilo della base di conoscenza
       retractall(is_member(field(Name, _, _), ClassName)),
+
+      %% Controlla che il valore del field sia del tipo del field
       type_check(Type, Value),
+
+      %% e sostituiscilo con il field della classe stessa
       asserta(is_member(field(Name, Value, Type), ClassName)),
       add_part(ClassName, OtherParts).
 
@@ -97,8 +116,11 @@ add_part(ClassName, [field(Name, Value, Type) | OtherParts]) :-
       is_class(ClassName),
       \+ is_member(field(Name, _, _), ClassName),
       !,
-      retractall(is_member(field(Name, _, _), ClassName)),
+
+      %% Se il field non è anche un field di una superclass
+      %% controlla che il valore del field sia del tipo del field
       type_check(Type, Value),
+      %% e di che è un field di questa classe
       asserta(is_member(field(Name, Value, Type), ClassName)),
       add_part(ClassName, OtherParts).
 
@@ -106,9 +128,12 @@ add_part(ClassName, [method(Name, ArgList, Body) | OtherParts]) :-
       is_list(ArgList),
       is_class(ClassName),
       asserta(is_member(method(Name, ArgList, Body), ClassName)),
+
+      %% Ricava il termine composto che rappresenta la testa del predicato
       Head =.. [Name, InstanceName | ArgList],
       !,
-      replace(this,InstanceName,Body,NewBody),
+
+      replace(this, InstanceName, Body, NewBody),
       asserta(Head :- (is_instance(InstanceName, ClassName), NewBody, !)),
       add_part(ClassName, OtherParts).
 
@@ -116,7 +141,9 @@ set_superclass_fields(_InstanceName, _ClassName, []) :- !.
 set_superclass_fields(InstanceName,
               ClassName,
               [[Name, Value, Type] | OtherFields]) :-
+    %% Controlla che il valore sia del tipo corretto
     type_check(Type, Value),
+
     assertz(field(InstanceName, Name, Value)),
     set_superclass_fields(InstanceName, ClassName, OtherFields).
 
@@ -124,33 +151,43 @@ set_fields(_InstanceName, _ClassName, []) :- !.
 set_fields(InstanceName,
               ClassName,
               [=(Name, Value) | OtherFields]) :-
+    %% Controlla che `Name` sia un field dell'istanza
     field(InstanceName, Name, OldValue),
+    %% ed un membro della classe
     is_member(field(Name, _Value, Type), ClassName),
+
+    %% Controlla che il nuovo valore sia del tipo corretto
     type_check(Type, Value),
-    retractall(field(InstanceName, Name, OldValue)),
     !,
+
+    %% Rimuove della base di conoscenza il vecchio field
+    retractall(field(InstanceName, Name, OldValue)),
+    %% e lo aggiorna con il nuovo valore
     asserta(field(InstanceName, Name, Value)),
+
     set_fields(InstanceName, ClassName, OtherFields).
 
+%% Se arriva a questo caso si è verificato un errore
+%% e deve eliminare le informazioni residue
+%% della creazione dell'istanza
 set_fields(InstanceName, _ClassName, _Fields) :-
     retractall(is_instance(InstanceName)),
     retractall(is_instance(InstanceName, _)),
     retractall(field(InstanceName, _, _)),
-    !,
     fail().
 
-replace(Subterm0, Subterm, Term0, Term) :-
-       Term0 == Subterm0,
-       !,
-       Term = Subterm.
-replace(_Subterm0, _Subterm, Term0, Term) :-
-       var(Term0),
-       !,
-       Term = Term0.
-replace(Subterm0, Subterm, Term0, Term) :-
-       Term0 =.. [F | Args0],
-       maplist(replace(Subterm0,Subterm), Args0, Args),
-       Term =.. [F | Args].
+replace(OldTerm, NewTerm, Body, NewTerm) :- Body == OldTerm, !.
+replace(_OldTerm, _NewTerm, Body, Body) :- var(Body), !.
+replace(OldTerm, NewTerm, Body, Result) :-
+       Body =.. [Funct | BodyFunctArgs],
+
+       %% Chiama ricorsivamente `replace` sugli argomenti di `Body`
+       maplist(replace(OldTerm,NewTerm), BodyFunctArgs, NewFunctArgs),
+
+       %% Ricostruisci il termine composto con:
+       %% - stesso funtore di `Body`
+       %% - argomenti a cui è stata applicata la `replace`
+       Result =.. [Funct | NewFunctArgs].
 
 type_check(_X, nil) :- !.
 type_check(nil, _X) :- !.
@@ -201,6 +238,8 @@ set_superclass(ClassName, [Parent | OtherParents]) :-
     asserta(is_child_of(Parent, ClassName)),
     def_class(ClassName, OtherParents),
 
+    %% Trova tutti i field/method del genitore
+    %% e aggiungili alla classe figlio
     findall(Part,
            is_member(Part, Parent),
            ParentParts),
@@ -208,22 +247,25 @@ set_superclass(ClassName, [Parent | OtherParents]) :-
 
 wrapped_make(InstanceName, ClassName, Fields) :-
     is_list(Fields),
-    !,
-    instanciate_superclass(InstanceName, ClassName),
-    set_fields(InstanceName, ClassName, Fields).
-
-instanciate_superclass(InstanceName, ClassName) :-
     atom(InstanceName),
     nonvar(ClassName),
     is_class(ClassName),
     \+ is_instance(InstanceName),
-    !,
+
     asserta(is_instance(InstanceName)),
     asserta(is_instance(InstanceName, ClassName)),
 
+    instanciate_superclass(InstanceName, ClassName),
+    set_fields(InstanceName, ClassName, Fields).
+
+instanciate_superclass(InstanceName, ClassName) :-
+    %% Trova tutti i field della classe da istanziare
+    %% e raggruppali in terne (nome, valore, tipo)
     findall([Name, Value, Type],
            is_member(field(Name, Value, Type), ClassName),
            Fields),
+
+    %% Dì per ogni field che è `field` dell'instance `InstanceName`
     set_superclass_fields(InstanceName, ClassName, Fields).
 
 search_instance(InstanceName, ClassName, [=(Field,Value) | Other]) :-