14
15:- module(logicmoo_util_engines,
16 [ result_check/3,
17 on_diff_fail/2,
18 on_diff_throw/2,
19 call_diff/3,
20 intersect_eq0/3,
21 22 collecting_list/4,
23
24 start_listening/1,
25 call_in_engine/1,
26 start_goal_saved1/0,
27 wait_until_next_request/0,
28 next_solution/0,
29 next_solution/1
30 ]). 31
32:- meta_predicate
33 collecting_list(0,+,+,+),
34 result_check(0,+,+),
35 call_in_engine(0),
36 on_diff_throw(0,0),
37 on_diff_fail(0,0),
38 call_diff(2,0,0). 39
40
41
42result_check(Call, _ + NVs, _ + OVs):-
43 NVs=@=OVs -> true; Call.
44
45
57
58on_diff_fail(Left,Right):-
59 call_diff(result_check(fail),Left,Right).
60
61on_diff_throw(Left,Right):-
62 call_diff(result_check(trace_or_throw(different(Left,Right))),Left,Right).
63
64call_diff(Check,Left,Right):-
65 shared_vars(Left,Right,Vs),
66 67 copy_term(Right+Vs,CO+CVs),
68 69 NOL = saved_in([],[]),
70 collecting_list(call(CO),CVs,1,NOL),
71 collecting_list(call(Left),Vs,2,NOL),
72 call(Check,Left+Vs,Right+CVs).
73
74collecting_list(G,Vs,At,S):-
75 call(G),copy_term(Vs,CVs),
76 arg(At,S,Was),nb_setarg(At,S,[CVs|Was]).
77
78
79:- thread_initialization(nb_setval(query_result,sol(0,1,false,false))). 80
82next_solution:- quietly(next_solution(How)),call(How).
83
84next_solution(throw(no_query_result)) :- \+ nb_current(query_result,_),!.
85next_solution(request_next0) :- nb_getval(query_result,sol(_,_,true,false)),!.
86next_solution(nop(last(G))) :- nb_getval(query_result,sol(_,G,true,true)),!.
87next_solution(request_next0) :- nb_getval(query_result,sol(_,_,_,false)),!.
88next_solution(nop(unknown(QR))) :- nb_getval(query_result,QR),!.
89
90request_next0 :-
91 quietly((thread_send_message(ask1,please(next_sol)), !,
92 thread_get_message(answer1,M),wdmsg(rn(M)),nb_setval(query_result,M))),!.
93
94call_in_engine(G):-
95 once((nb_setval(in,v(_,G,_)),
96 start_goal_saved1)),fail.
97call_in_engine(G):- next_solution, get_sol(G).
98
99
100get_sol(G):-
101 repeat,
102 next_solution,
103 nb_getval(query_result,M),
104 react_message(M,G,(ReactA,ReactB)),
105 wdmsg(M),
106 (ReactA == ! -> ! ; ReactA),
107 ReactB.
108
109react_message(sol(_,_,unknown,false),_,(true,fail)):-!.
110react_message(sol(_,_,false,_),_,(!,fail)):- !.
111react_message(sol(_,G,true,false),G,(true,true)):-!.
112react_message(sol(_,G,true,true),G,(!,true)):- !.
113
114
115call_goal_in_thread_saved_nd:- start_goal_saved1, fail.
116call_goal_in_thread_saved_nd:- next_solution.
117
118:- message_queue_property(_Queue, alias(answer1)) -> true;message_queue_create(_,[alias(answer1)]). 119:- message_queue_property(_Queue, alias(ask1)) -> true;message_queue_create(_,[alias(ask1)]). 120
121
122start_goal_saved1:-
123 quietly((nb_getval(in,v(_,G,_,_)),
124 thread_create(start_listening(G),_ID,[detached(true)]))),
125 nb_setval(query_result,sol(0,G,unknown,false)),!.
126
127wait_until_next_request:-
128 thread_get_message(ask1,please(C),[]),
129 (C == more_sols -> true; (C == completed -> (!,fail) ; (true))).
130
131thread_send_answer(Left,G,TF,Done):- wdmsg(next_________sol(Left,G,TF,Done)), thread_send_message(answer1,sol(Left,G,TF,Done)).
132
133:- meta_predicate start_listening(0). 134start_listening(G):-
135 quietly((flag(sol,_,0),
136 ((thread_send_answer(0,G,unknown,false)),
137 thread_get_message(ask1,please(next_sol),[]),
138 ignore(((
139 ((G,deterministic(Det),flag(sol,I,I+1))
140 *-> (flag(sol,X,X),thread_send_answer(X,G,true,Det),wait_until_next_request) ;
141 flag(sol,X,X),thread_send_answer(X,G,false,true))
142 ),fail))))).
143
144
145intersect_eq0([], _, []).
146intersect_eq0([X|Xs], Ys, L) :-
147 ( member_eq0(X, Ys)
148 -> L = [X|T],
149 intersect_eq0(Xs, Ys, T)
150 ; intersect_eq0(Xs, Ys, L)
151 )