1:- module(obj,
    2	  [obj/3, obj_clear/2, obj_get/2, obj_get/3, obj_act/3, obj_act/5,
    3	  obj_init/2, obj_init/3, obj_init/4, obj_merge/3,
    4	  obj_merge_add/3, obj_pull/3, obj_pull_one/3, obj_push/3,
    5	  obj_put/3, obj_update/3, obj_update_one/3,
    6	  obj_default/3
    7	  ]).    8
    9		/*************
   10		*     obj    *
   11		*************/
?- obj([a(X), b(Y),c(Z)], [c(3), b(2), a(1)], U). ?- obj(get([a(X)]), [c(3), b(2), a(1)], U). ?- obj(put([a(4)]), [c(3), b(2), a(1)], U). ?- obj(pull([a(X), b(Y)]), [c(3), b(2), a(1)], U). ?- obj(push([a(4)]), [c(3), b(2), a(1)], U). ?- obj(append([a(4)]), [c(3), b(2), a(1)], U). ?- obj(select(a(X)), [c(3), b(2), a(1)], U). ?- obj_pull([a(1)], [a(1),a(2), a(1)], X). ?- obj_update([a(1),b(2)], [b(4),c(5), a(3)], R). ?- obj(act(a, b, =), [a(hello)], X). ?- obj(act(a, a, =), [a(hello)], X). ?- obj_act(a, =, [a(hello)], X). ?- obj_act(a, pred([A,A]:- writeln(A)), [a(hello)], X).
   28%
   29obj([], Y, Y)		:-!.
   30obj([A|B], Y, Y)	:-!, subset([A|B], Y).
   31obj((A,B), Y, Z)	:-!, obj(A, Y, Y0), obj(B, Y0, Z).
   32obj(get(X), Y, Z)	:-!, obj_get(X, Y, Z).
   33obj(put(X), Y, Z)	:-!, obj_put(X, Y, Z).
   34obj(push(X), Y, Z)	:-!, obj_push(X, Y, Z).
   35obj(pull(X), Y, Z)	:-!, obj_pull(X, Y, Z).
   36obj(update(X), Y, Z):-!, obj_update(X, Y, Z).
   37obj(merge(X), Y, Z)	:-!, obj_merge(X, Y, Z).
   38obj(default(X), Y, Z)	:-!, obj_default(X, Y, Z).
   39obj(act(A, B, G), X, Y)	:-!, obj_act(A, B, G, X, Y).
   40obj(act(A, G), X, Y):-!, obj_act(A, G, X, Y).
   41obj(act(G), X, Y)	:-!, obj_act(G, X, Y).
   42obj(X, Y, Z)		:- call(X, Y, Z).
   43
   44% meta
   45obj_get(X, Y)	:- subset(X, Y).
   46obj_get(X, Y, Y):- subset(X, Y).
   47obj_put(X, Y, Z):- obj_update(X, Y, Z).
   48obj_push(X, Y, Z):- append(X, Y, Z).
   49obj_pull(X, Y, Z):- foldl(obj_pull_one, X, Y, Z).
   50obj_update(X, Y, Z):- foldl(obj_update_one, X, Y, Z).
   51obj_default(X, Y, Z):- foldl(obj_default_one, X, Y, Z).
   52obj_clear(_, []).
   53
   54% obj helpers
   55
   56obj_pull_one(A, X, Y):- (select(A, X, Y) -> true; Y=X).
   57%
   58obj_update_one(A, B, [A|B0]) :- functor(A, F, 1),
   59	functor(A0, F, 1),
   60	select(A0, B, B0),
   61	!.
   62obj_update_one(A, B, [A|B]).
   63
   64% ?- obj_default([a(2)], [a(1)], X).
   65% ?- obj(default([a(1)]), [], R).
   66% ?- obj(default([a(X)]), [], R).
   67
   68obj_default_one(A, B, C):- functor(A, F, 1),
   69	functor(A0, F, 1),
   70	(	memberchk(A0, B) ->
   71		(	A0 = A -> C = B
   72		;	C = B
   73		)
   74	; 	C = [A|B]
   75	).
   76
   77% ?- obj_merge([a(2)], [a(1)], X). % false
   78% ?- obj_merge([b(2)], [a(1)], X).
   79obj_merge([])-->[].
   80obj_merge([X|Y]) --> obj_merge_add(X), obj_merge(Y).
   81%
   82obj_merge_add(X, Y, Z):- functor(X, A, N),
   83	functor(X0, A, N),
   84	(	memberchk(X0, Y) ->
   85		X0 = X,
   86		Z = Y
   87	;	Z=[X|Y]
   88	).
   89
   90% ?- obj_act(a, b, =, [a(hello)], X).
   91% ?- obj_act(a, a, =, [a(hello)], X).
   92% ?- obj_act(a, write, [a(hello)], X).
   93% ?- obj_act(a, =, [a(hello)], X).
   94% ?- obj_act(a, pred([A,A]:- writeln(A)), [a(hello)], X).
   95
   96:- meta_predicate obj_act(?,?,2,?,?).   97obj_act(A, B, G, X, Y):- A0 =.. [A, V],
   98	obj_pull([A0], X, X0),
   99	obj_solve(G, V, W),
  100	B0 =.. [B, W],
  101	obj_push([B0], X0, Y).
  102%
  103obj_solve(true, A, A):-!.
  104obj_solve((X,Y), A, B):-!, obj_solve(X, A, A0),
  105						obj_solve(Y, A0, B).
  106obj_solve(X, A, B):- call(X, A, B).
  107
  108:- meta_predicate obj_act(?,2,?,?).  109%
  110obj_act(A, G, X, Y):- obj_act(A, A, G, X, Y).
  111
  112% :- meta_predicate obj_act(2,?,?).
  113obj_act(G, X, Y):- obj_act(acc, acc, G, X, Y).
  114
  115%
  116obj_init(X, [acc(X)]).
  117%
  118obj_init(Objs, X, [acc(X)|Objs]).
  119%
  120obj_init(A, Objs, X, [B|Objs]):- functor(B, A, 1), arg(1, B, X)