From: LeonardoBizzoni Date: Wed, 13 Dec 2023 13:10:44 +0000 (+0100) Subject: Cominciato a fare la `make` X-Git-Url: http://git.leonardobizzoni.com/?a=commitdiff_plain;h=fd9c0b71bead74b43147d463414cddfe9b59cd76;p=ObjectOriented-Prolog-Lisp Cominciato a fare la `make` Manca il controllo sul tipo di `field`. Ho modificato la `def_class` per far aggiungere alla classe figlio le parti di tutte le classi genitore. `make` senza field aggiuntivi chiama la `set_default_fields_for` per aggiungere a questa instance tutte le parte come `field`. La `make` con field aggiuntivi imposta quelli di default e poi tramite `set_fields_for` rimuove dalla base di conosceza i field da aggiornare lasciando solo quelli nuovi. Ancora non so cosa fare ne coi metodi ne come sostituire `this` nel corpo di un metodo con l'istanza stessa. --- diff --git a/Prolog/README.org b/Prolog/README.org index 066d17f..0bff62e 100644 --- a/Prolog/README.org +++ b/Prolog/README.org @@ -18,7 +18,12 @@ def_class(ClassName, []) :- asserta(is_class(ClassName)), !. def_class(ClassName, [Parent | OtherParents]) :- is_class(Parent), asserta(is_child_of(Parent, ClassName)), - def_class(ClassName, OtherParents). + def_class(ClassName, OtherParents), + + findall(Part, + is_part_of(Parent, Part), + ParentParts), + add_part_to(ClassName, ParentParts). def_class(ClassName, [], []) :- def_class(ClassName, []), !. def_class(ClassName, Parents, Parts) :- @@ -35,6 +40,25 @@ def_class(ClassName, Parents, Parts) :- *** Implementazione #+begin_src prolog :tangle oop.pl +make(InstanceName, ClassName) :- make(InstanceName, ClassName, []). +make(InstanceName, ClassName, []) :- + is_class(ClassName), + \+ is_instance(InstanceName), + !, + asserta(is_instance(InstanceName)), + asserta(is_instance(InstanceName, ClassName)), + + findall([Name, Value, Type], + ((is_part_of(ClassName, field(Name, Value)), Type = nil); + is_part_of(ClassName, field(Name, Value, Type))), + Fields), + set_default_fields_for(InstanceName, ClassName, Fields). + +make(InstanceName, ClassName, [Field | Other]) :- + [Field | Other] = Fields, + !, + make(InstanceName, ClassName, []), + set_fields_for(InstanceName, ClassName, Fields). #+end_src *** Esempio pratico @@ -46,6 +70,7 @@ def_class(ClassName, Parents, Parts) :- *** Implementazione #+begin_src prolog :tangle oop.pl +:- dynamic field/3. #+end_src *** Esempio pratico @@ -67,30 +92,82 @@ def_class(ClassName, Parents, Parts) :- :- dynamic is_class/1. :- dynamic is_child_of/2. :- dynamic is_part_of/2. +:- dynamic is_instance/1. +:- dynamic is_instance/2. #+end_src ** add_part_to #+begin_src prolog :tangle oop.pl add_part_to(ClassName, []) :- is_class(ClassName), !. add_part_to(ClassName, [Part | OtherParts]) :- - field(_Name, _Value) = Part, - !, + field(Name, _Value) = Part, is_class(ClassName), + ( + ( + is_part_of(ClassName, field(Name, _)); + is_part_of(ClassName, field(Name, _, _)) + ), + retractall(is_part_of(ClassName, field(Name, _))), + retractall(is_part_of(ClassName, field(Name, _, _))); + true() + ), + !, asserta(is_part_of(ClassName, Part)), add_part_to(ClassName, OtherParts). add_part_to(ClassName, [Part | OtherParts]) :- - field(_Name, _Value, _Type) = Part, - !, + field(Name, _Value, _Type) = Part, is_class(ClassName), + ( + ( + is_part_of(ClassName, field(Name, _)); + is_part_of(ClassName, field(Name, _, _)) + ), + retractall(is_part_of(ClassName, field(Name, _))), + retractall(is_part_of(ClassName, field(Name, _, _))); + true() + ), + !, asserta(is_part_of(ClassName, Part)), add_part_to(ClassName, OtherParts). add_part_to(ClassName, [Part | OtherParts]) :- method(_Name, ArgList, _Form) = Part, is_list(ArgList), - !, is_class(ClassName), asserta(is_part_of(ClassName, Part)), add_part_to(ClassName, OtherParts). #+end_src + +** set_default_fields_for +#+begin_src prolog :tangle oop.pl +set_default_fields_for(_InstanceName, _ClassName, []) :- !. +set_default_fields_for(InstanceName, + ClassName, + [[Name, Value, _Type] | OtherFields]) :- + % Controlli sul tipo + + % Aggingi i field + assertz(field(InstanceName, Name, Value)), + set_default_fields_for(InstanceName, ClassName, OtherFields). +#+end_src + +** set_fields_for +#+begin_src prolog :tangle oop.pl +set_fields_for(_InstanceName, _ClassName, []) :- !. +set_fields_for(InstanceName, + ClassName, + [=(Name, Value) | OtherFields]) :- + field(InstanceName, Name, OldValue), + retractall(field(InstanceName, Name, OldValue)), + !, + asserta(field(InstanceName, Name, Value)), + set_fields_for(InstanceName, ClassName, OtherFields). + +set_fields_for(InstanceName, _ClassName, _Fields) :- + retractall(is_instance(InstanceName)), + retractall(is_instance(InstanceName, _)), + retractall(field(InstanceName, _, _)), + !, + fail(). +#+end_src diff --git a/Prolog/oop.pl b/Prolog/oop.pl index 3852766..25396da 100644 --- a/Prolog/oop.pl +++ b/Prolog/oop.pl @@ -5,42 +5,111 @@ def_class(ClassName, []) :- asserta(is_class(ClassName)), !. def_class(ClassName, [Parent | OtherParents]) :- is_class(Parent), asserta(is_child_of(Parent, ClassName)), - def_class(ClassName, OtherParents). + def_class(ClassName, OtherParents), + + findall(Part, + is_part_of(Parent, Part), + ParentParts), + add_part_to(ClassName, ParentParts). def_class(ClassName, [], []) :- def_class(ClassName, []), !. def_class(ClassName, Parents, Parts) :- def_class(ClassName, Parents), add_part_to(ClassName, Parts). +make(InstanceName, ClassName) :- make(InstanceName, ClassName, []). +make(InstanceName, ClassName, []) :- + is_class(ClassName), + \+ is_instance(InstanceName), + !, + asserta(is_instance(InstanceName)), + asserta(is_instance(InstanceName, ClassName)), + findall([Name, Value, Type], + ((is_part_of(ClassName, field(Name, Value)), Type = nil); + is_part_of(ClassName, field(Name, Value, Type))), + Fields), + set_default_fields_for(InstanceName, ClassName, Fields). +make(InstanceName, ClassName, [Field | Other]) :- + [Field | Other] = Fields, + !, + make(InstanceName, ClassName, []), + set_fields_for(InstanceName, ClassName, Fields). +:- dynamic field/3. :- dynamic is_class/1. :- dynamic is_child_of/2. :- dynamic is_part_of/2. +:- dynamic is_instance/1. +:- dynamic is_instance/2. add_part_to(ClassName, []) :- is_class(ClassName), !. add_part_to(ClassName, [Part | OtherParts]) :- - field(_Name, _Value) = Part, - !, + field(Name, _Value) = Part, is_class(ClassName), + ( + ( + is_part_of(ClassName, field(Name, _)); + is_part_of(ClassName, field(Name, _, _)) + ), + retractall(is_part_of(ClassName, field(Name, _))), + retractall(is_part_of(ClassName, field(Name, _, _))); + true() + ), + !, asserta(is_part_of(ClassName, Part)), add_part_to(ClassName, OtherParts). add_part_to(ClassName, [Part | OtherParts]) :- - field(_Name, _Value, _Type) = Part, - !, + field(Name, _Value, _Type) = Part, is_class(ClassName), + ( + ( + is_part_of(ClassName, field(Name, _)); + is_part_of(ClassName, field(Name, _, _)) + ), + retractall(is_part_of(ClassName, field(Name, _))), + retractall(is_part_of(ClassName, field(Name, _, _))); + true() + ), + !, asserta(is_part_of(ClassName, Part)), add_part_to(ClassName, OtherParts). add_part_to(ClassName, [Part | OtherParts]) :- method(_Name, ArgList, _Form) = Part, is_list(ArgList), - !, is_class(ClassName), asserta(is_part_of(ClassName, Part)), add_part_to(ClassName, OtherParts). + +set_default_fields_for(_InstanceName, _ClassName, []) :- !. +set_default_fields_for(InstanceName, + ClassName, + [[Name, Value, _Type] | OtherFields]) :- + % Controlli sul tipo + + % Aggingi i field + assertz(field(InstanceName, Name, Value)), + set_default_fields_for(InstanceName, ClassName, OtherFields). + +set_fields_for(_InstanceName, _ClassName, []) :- !. +set_fields_for(InstanceName, + ClassName, + [=(Name, Value) | OtherFields]) :- + field(InstanceName, Name, OldValue), + retractall(field(InstanceName, Name, OldValue)), + !, + asserta(field(InstanceName, Name, Value)), + set_fields_for(InstanceName, ClassName, OtherFields). + +set_fields_for(InstanceName, _ClassName, _Fields) :- + retractall(is_instance(InstanceName)), + retractall(is_instance(InstanceName, _)), + retractall(field(InstanceName, _, _)), + !, + fail().