From: LeonardoBizzoni Date: Sun, 24 Dec 2023 10:20:25 +0000 (+0100) Subject: La Mirko-alternativa X-Git-Url: http://git.leonardobizzoni.com/?a=commitdiff_plain;h=cb2c01e841616250ef1dc4185009e4d4271fea2a;p=ObjectOriented-Prolog-Lisp La Mirko-alternativa --- diff --git a/Prolog/README.org b/Prolog/README.org index b23a6f2..8b707bf 100644 --- a/Prolog/README.org +++ b/Prolog/README.org @@ -237,8 +237,10 @@ add_part(ClassName, [method(Name, ArgList, Body) | OtherParts]) :- asserta(is_member(method(Name, ArgList, Body), ClassName)), - Fn =.. [Name, Instance | ArgList], - asserta(Fn :- (call_method(Instance, ClassName, Body), !)), + Head =.. [Name, InstanceName | ArgList], + !, + edit_body(InstanceName, Body, NewBody), + asserta(Head :- (call_method(InstanceName, ClassName, NewBody))), add_part(ClassName, OtherParts). #+end_src @@ -286,29 +288,43 @@ check_fields(InstanceName, [=(Field, Value) | Other]) :- check_fields(InstanceName, Other). #+end_src -** define_this -#+begin_src prolog :tangle oop.pl -define_this(Instance) :- - \+ is_list(Instance), - !, - findall(Key = Value, field(Instance, Key, Value), List), - define_this(List). - -define_this([]) :- !. -define_this([=(Key, Value) | Other]) :- - asserta(field(this, Key, Value)), - define_this(Other). -#+end_src - ** call_method #+begin_src prolog :tangle oop.pl call_method(Instance, ClassName, Body) :- is_instance(Instance, ClassName), asserta(is_instance(this, ClassName)), - define_this(Instance), call_cleanup(call(Body), ( - retractall(is_instance(this, ClassName)), - retractall(field(this, _, _)))). + retractall(is_instance(this, ClassName)))). +#+end_src + +** edit_body +#+begin_src prolog +edit_body(InstanceName, OldBody, NewBody) :- + conjunction_to_list(OldBody, BodyList), + replace(field(this, Name, Value), field(InstanceName, Name, Value), BodyList, Result), + list_to_conjunction(Result, NewBody). + #+end_src + +** conjunction_to_list +#+begin_src prolog +conjunction_to_list(Body, [P | Ps]) :- + Body = (P, Conjuncts), + !, + conjunction_to_list(Conjuncts, Ps). +conjunction_to_list(Predicate, [Predicate]) :- !. +#+end_src + +** list_to_conjunction +#+begin_src prolog +list_to_conjunction([], true). +list_to_conjunction([P|Ps], (P, Conjuncts)) :- list_to_conjunction(Ps, Conjuncts). +#+end_src + +** replace +#+begin_src prolog +replace(_, _, [], []) :- !. +replace(Old, New, [Old | L1], [New | L2]) :- !, replace(Old, New, L1, L2). +replace(Old, New, [E | L1], [E | L2]) :- E \= Old, !, replace(Old, New, L1, L2). #+end_src ** check_value_type diff --git a/Prolog/oop.pl b/Prolog/oop.pl index 3ec30c9..d2f3ba4 100644 --- a/Prolog/oop.pl +++ b/Prolog/oop.pl @@ -95,7 +95,7 @@ fieldx(Instance, [FieldName], Res) :- !. fieldx(Instance, [FieldName | Others], Res) :- is_instance(Instance), - field(Instance, FieldName, Value), + field(Instance, FieldName, _Value), fieldx(Instance, Others, Res). :- dynamic is_class/1. @@ -155,8 +155,10 @@ add_part(ClassName, [method(Name, ArgList, Body) | OtherParts]) :- asserta(is_member(method(Name, ArgList, Body), ClassName)), - Fn =.. [Name, Instance | ArgList], - asserta(Fn :- (call_method(Instance, ClassName, Body), !)), + Head =.. [Name, InstanceName | ArgList], + !, + edit_body(InstanceName, Body, NewBody), + asserta(Head :- (call_method(InstanceName, ClassName, NewBody))), add_part(ClassName, OtherParts). @@ -194,24 +196,30 @@ check_fields(InstanceName, [=(Field, Value) | Other]) :- field(InstanceName, Field, Value), check_fields(InstanceName, Other). -define_this(Instance) :- - \+ is_list(Instance), - !, - findall(Key = Value, field(Instance, Key, Value), List), - define_this(List). - -define_this([]) :- !. -define_this([=(Key, Value) | Other]) :- - asserta(field(this, Key, Value)), - define_this(Other). - call_method(Instance, ClassName, Body) :- is_instance(Instance, ClassName), asserta(is_instance(this, ClassName)), - define_this(Instance), call_cleanup(call(Body), ( - retractall(is_instance(this, ClassName)), - retractall(field(this, _, _)))). + retractall(is_instance(this, ClassName)))). + +edit_body(InstanceName, OldBody, NewBody) :- + conjunction_to_list(OldBody, BodyList), + replace(field(this, Name, Value), field(InstanceName, Name, Value), BodyList, Result), + list_to_conjunction(Result, NewBody). + +conjunction_to_list(Body, [P | Ps]) :- + Body = (P, Conjuncts), + !, + conjunction_to_list(Conjuncts, Ps). +conjunction_to_list(Predicate, [Predicate]) :- !. + +list_to_conjunction([], true). +list_to_conjunction([P|Ps], (P, Conjuncts)) :- list_to_conjunction(Ps, Conjuncts). + +replace(_, _, [], []) :- !. +replace(Old, New, [Old | L1], [New | L2]) :- !, replace(Old, New, L1, L2). +replace(Old, New, [E | L1], [E | L2]) :- E \= Old, !, replace(Old, New, L1, L2). + check_value_type(nil, _X) :- !. check_value_type(var, X) :- var(X), !.