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
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
!.
fieldx(Instance, [FieldName | Others], Res) :-
is_instance(Instance),
- field(Instance, FieldName, Value),
+ field(Instance, FieldName, _Value),
fieldx(Instance, Others, Res).
:- dynamic is_class/1.
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).
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), !.