2:- module(no_repeats,
3 [ 12 must_not_repeat/1,
13 no_repeats/1,
14 no_repeats/2,
29 subtract_eq/3,
30 no_repeats_var/1
32 ]).
39:- meta_predicate
40 memberchk_pred(2, ?, ?),
41 memberchk_pred_rev(2, ?, ?),
42 must_not_repeat(0),
43 no_repeats(0),
44 no_repeats(+, 0),
45 no_repeats_findall5(+, 0, -, -, -),
46 no_repeats_findall_r(+, 0, -, -, -),
47 no_repeats_old(0),
48 no_repeats_old(+, 0),
49 no_repeats_cmp(2, +, 0),
50 no_repeats_save(+, 0),
51 no_repeats_save(+, 0, -, -),
52 no_repeats_u(+, 0),
53 loop_check_nr(0),
54 succeeds_n_times(0, -). 55:- module_transparent
56 memberchk_same/2,
57 no_repeats_av/0,
58 no_repeats_cmp/3,
59 subtract_eq/3,
60 nr_test/2. 61
62
63:- set_module(class(library)). 64
72loop_check_nr(CL):- loop_check(no_repeats(CL)).
73
74
76
77:- thread_local tlbugger:attributedVars/0. 78
80
81:- export(must_not_repeat/1).
90must_not_repeat(C):-call(C).
91
114no_repeats_av:-tlbugger:attributedVars.
115
116:- export(no_repeats/1). 117:- meta_predicate no_repeats(0). 118
128no_repeats(Call):- no_repeats_old(Call).
129
130
131:- export(no_repeats/2). 132:- meta_predicate no_repeats(+,0).
142no_repeats(Vs,Call):- no_repeats_old(Vs,Call).
143
149
161:- export(no_repeats_old/1). 162:- meta_predicate no_repeats_old(0).
170no_repeats_old(Call):- no_repeats_old(Call,Call).
171
172
182memberchk_same(X, List) :- is_list(List),!, \+ atomic(List), C=..[v|List],(var(X)-> (arg(_,C,YY),X==YY) ; (arg(_,C,YY),X =@= YY)),!.
183memberchk_same(X, Ys) :- nonvar(Ys), var(X)->memberchk_same0(X, Ys);memberchk_same1(X,Ys).
184memberchk_same0(X, [Y|Ys]) :- X==Y ; (nonvar(Ys),memberchk_same0(X, Ys)).
185memberchk_same1(X, [Y|Ys]) :- X =@= Y ; (nonvar(Ys),memberchk_same1(X, Ys)).
186
187memberchk_same2(X, List) :- Hold=hold(List), !,
188 repeat, (arg(1,Hold,[Y0|Y0s]) ->
189 ( X==Y0-> true; (nb_setarg(1,Hold,Y0s),fail)) ; (! , fail)).
190
191memberchk_same3(X, List) :- Hold=hold(List), !,
192 repeat, (arg(1,Hold,[Y0|Y0s]) ->
193 ( X=@=Y0-> true; (nb_setarg(1,Hold,Y0s),fail)) ; (! , fail)).
194
195memb_r(X, List) :- Hold=hold(List), !, trace_or_throw(broken_memb_r(X, List)),
196 repeat,
197 ((arg(1,Hold,[Y|Ys]),nb_setarg(1,Hold,Ys)) -> X=Y ; (! , fail)).
210memberchk_pred(Pred, X, [Y0|Ys]) :- is_list(Ys),C=..[v,Y0|Ys],!, arg(_,C,Y), call(Pred,X,Y),!.
211memberchk_pred(Pred, X, [Y|Ys]) :- ( call(Pred,X,Y) -> true ; (nonvar(Ys),memberchk_pred(Pred, X, Ys) )).
219memberchk_pred_rev(Pred, X, [Y0|Ys]) :- is_list(Ys),C=..[v,Y0|Ys],!, arg(_,C,Y), call(Pred,Y,X),!.
220memberchk_pred_rev(Pred, X, [Y|Ys]) :- ( call(Pred,Y,X) -> true ; (nonvar(Ys),memberchk_pred_rev(Pred,X, Ys) )).
221
222:- export(no_repeats_old/2). 223:- meta_predicate no_repeats_old(+,0).
231no_repeats_old(Vs,Call):- ground(Vs),!,Call,!.
232no_repeats_old(Vs,Call):- CONS = [_], (Call),
233 quietly(( \+ memberchk_same(Vs,CONS), copy_term(Vs,CVs), CONS=[_|T], nb_setarg(2, CONS, [CVs|T]))).
234
237
238no_repeats_cmp(_,Vs,Call):- ground(Vs),!,Call,!.
239no_repeats_cmp(Cmp,Vs,Call):- CONS = [zzzZZZZzzzzZZZ], (Call),
240 quietly(( \+ memberchk_cmp(Cmp,Vs,CONS), copy_term(Vs,CVs), CONS=[_|T], nb_setarg(2, CONS, [CVs|T]))).
241:- export(no_repeats_cmp/3). 242memberchk_cmp(Cmp,Vs,CONS):-
243 member(XY,CONS),call(Cmp,Vs,XY),!.
244
249
251
252:- export(no_repeats_u/2). 253:- meta_predicate no_repeats_u(+,0).
261no_repeats_u(Vs,Call):- CONS = [_], (Call), ( CONS=[_|T],
262 \+ memberchk_pred_rev(subsumes_term,Vs,T), copy_term(Vs,CVs), nb_setarg(2, CONS, [CVs|T]))).
263
264
265
283subtract_eq([],_,[]) :- !.
284subtract_eq([E|Set], Delete, Result) :-
285 subtract_eq(Set, Delete, Mid),
286 (identical_memberchk(E,Delete)-> Result = Mid ; Result = [E|Mid]).
287
334
336:- meta_predicate succeeds_n_times(0, -).
346succeeds_n_times(Goal, Times) :-
347 Counter = counter(0),
348 ( Goal,
349 arg(1, Counter, N0),
350 N is N0 + 1,
351 nb_setarg(1, Counter, N),
352 fail
353 ; arg(1, Counter, Times)
354 ).
355
356
357
358:- export(no_repeats_findall5/5). 359:- meta_predicate no_repeats_findall5(+,0,-,-,-).
367no_repeats_findall5(Vs,Call,ExitDET,USE,NEW):-
368 (((HOLDER = fa([]),
369 Call,arg(1,HOLDER,CONS),
370 ((
371 (( \+ memberchk_same(Vs,CONS),
372 copy_term(Vs,CVs),
373 append(CONS,[CVs],NEW),
374 nb_setarg(1, HOLDER, NEW)))
375 ->
376 USE=true;
377 ((USE=(false),CONS=NEW))
378 )),
379 deterministic(ExitDET),true))
380 *-> true;
381 (NEW=[],ExitDET=true,USE=(false))).
382
383:- export(no_repeats_save/4). 384:- meta_predicate no_repeats_save(+,0,-,-).
392no_repeats_save(Vs,Call,Saved,USE):-
393 SavedHolder = saved(_),
394 no_repeats_findall5(Vs,Call,ExitDET,USE,NEW),
395 ( ExitDET==true -> (nb_linkarg(1,SavedHolder,NEW),!) ; true),
396 arg(1,SavedHolder,Saved).
397
398:- export(no_repeats_save/2). 399:- meta_predicate no_repeats_save(+,0).
407no_repeats_save(Vs,Call):-
408 call_cleanup(
409 (( no_repeats_save(Vs,Call,SavedList,USE),
410 (USE==true -> true ; fail))),
411 (is_list(SavedList) -> writeln(saving(SavedList)) ; writeln(givingup_on(Call)))).
412
413
414:- export(no_repeats_findall_r/5). 415:- meta_predicate no_repeats_findall_r(+,0,-,-,-).
423no_repeats_findall_r(Vs,Call,CONS,ExitDET,List):-
424 CONS = [ExitDET],
425 (Call,once(( \+ memberchk_same(Vs,CONS), copy_term(Vs,CVs), CONS=[_|T],List=[CVs|T], nb_linkarg(2, CONS, List)))),
426 deterministic(ExitDET).
439no_repeats_var(Var):- nonvar(Var) ->true;
440 (get_attr(Var,nr,_)->true;put_attr(Var,nr,old_vals(Var,same_forms,[]))).
441no_repeats_var(Cmp,Var):- nonvar(Var) ->true; (get_attr(Var,nr,_)->true;put_attr(Var,nr,old_vals(Var,Cmp,[]))).
442
443nr:attr_unify_hook(AttValue,VarValue):-
444 AttValue=old_vals(_Var,Cmp,Waz),
445 \+ memberchk_pred(Cmp,VarValue,Waz),nb_setarg(3,AttValue,[VarValue|Waz]).
452
453same_forms(F1,F2):- get_attrs(F1,A1),!,get_attrs(F2,A2),A1=@=A2.
454same_forms(F1,F2):- get_attrs(F2,A1),!,fail,get_attrs(F1,A2),A1=@=A2.
455same_forms(F1,F2):- var(F1),!,F2==F1.
456same_forms(F1,F2):- var(F2),!,fail,F2==F1.
457same_forms(F1,F2):- F1=@=F2.
459
460:- if(current_predicate(fixup_exports/0)). 461:- fixup_exports. 462:- endif.
468nr_test((-7), 3).
469nr_test(2,10).
470nr_test((-8), 5).
471nr_test((-8), 2).
472nr_test(42,11).
473nr_test(42,14).
474nr_test(1,3).
475nr_test(77,2).
476nr_test(80,10).
477nr_test(80,0).
478nr_test((-3),12).
479nr_test((-4), 14).
480nr_test((-4), 0).
481nr_test(45,0).
482nr_test(45,9).
483nr_test((-1),1)
Utility LOGICMOO NO REPEATS
No repeats allows each indiv answer returned by prolog to be unique. Removes duplicate answers.