Next: sparse_bitset, Previous: set_unordlist, Up: Top [Contents]
%--------------------------------------------------% % vim: ft=mercury ts=4 sw=4 et %--------------------------------------------------% % Copyright (C) 1994-2007 The University of Melbourne. % Copyright (C) 2014-2018 The Mercury team. % This file is distributed under the terms specified in COPYING.LIB. %--------------------------------------------------% % % File: solutions.m. % Main author: fjh. % Stability: medium. % %--------------------------------------------------% %--------------------------------------------------% :- module solutions. :- interface. :- import_module bool. :- import_module list. :- import_module set. %--------------------------------------------------% % solutions/2 collects all the solutions to a predicate and returns % them as a list in sorted order, with duplicates removed. % solutions_set/2 returns them as a set. unsorted_solutions/2 returns % them as an unsorted list with possible duplicates; since there are % an infinite number of such lists, this must be called from a context % in which only a single solution is required. % :- pred solutions(pred(T), list(T)). :- mode solutions(pred(out) is multi, out(non_empty_list)) is det. :- mode solutions(pred(out) is nondet, out) is det. :- func solutions(pred(T)) = list(T). :- mode solutions(pred(out) is multi) = out(non_empty_list) is det. :- mode solutions(pred(out) is nondet) = out is det. :- func solutions_set(pred(T)) = set(T). :- mode solutions_set(pred(out) is multi) = out is det. :- mode solutions_set(pred(out) is nondet) = out is det. :- pred solutions_set(pred(T), set(T)). :- mode solutions_set(pred(out) is multi, out) is det. :- mode solutions_set(pred(out) is nondet, out) is det. :- pred unsorted_solutions(pred(T), list(T)). :- mode unsorted_solutions(pred(out) is multi, out(non_empty_list)) is cc_multi. :- mode unsorted_solutions(pred(out) is nondet, out) is cc_multi. :- func aggregate(pred(T), func(T, U) = U, U) = U. :- mode aggregate(pred(out) is multi, func(in, in) = out is det, in) = out is det. :- mode aggregate(pred(out) is nondet, func(in, in) = out is det, in) = out is det. % aggregate/4 generates all the solutions to a predicate, % sorts them and removes duplicates, then applies an accumulator % predicate to each solution in turn: % % aggregate(Generator, AccumulatorPred, Acc0, Acc) <=> % solutions(Generator, Solutions), % list.foldl(AccumulatorPred, Solutions, Acc0, Acc). % :- pred aggregate(pred(T), pred(T, U, U), U, U). :- mode aggregate(pred(out) is multi, pred(in, in, out) is det, in, out) is det. :- mode aggregate(pred(out) is multi, pred(in, di, uo) is det, di, uo) is det. :- mode aggregate(pred(out) is nondet, pred(in, di, uo) is det, di, uo) is det. :- mode aggregate(pred(out) is nondet, pred(in, in, out) is det, in, out) is det. % aggregate2/6 generates all the solutions to a predicate, % sorts them and removes duplicates, then applies an accumulator % predicate to each solution in turn: % % aggregate2(Generator, AccumulatorPred, AccA0, AccA, AccB0, AccB) <=> % solutions(Generator, Solutions), % list.foldl2(AccumulatorPred, Solutions, AccA0, AccA, AccB0, AccB). % :- pred aggregate2(pred(T), pred(T, U, U, V, V), U, U, V, V). :- mode aggregate2(pred(out) is multi, pred(in, in, out, in, out) is det, in, out, in, out) is det. :- mode aggregate2(pred(out) is multi, pred(in, in, out, di, uo) is det, in, out, di, uo) is det. :- mode aggregate2(pred(out) is nondet, pred(in, in, out, di, uo) is det, in, out, di, uo) is det. :- mode aggregate2(pred(out) is nondet, pred(in, in, out, in, out) is det, in, out, in, out) is det. % unsorted_aggregate/4 generates all the solutions to a predicate % and applies an accumulator predicate to each solution in turn. % Declaratively, the specification is as follows: % % unsorted_aggregate(Generator, AccumulatorPred, Acc0, Acc) <=> % unsorted_solutions(Generator, Solutions), % list.foldl(AccumulatorPred, Solutions, Acc0, Acc). % % Operationally, however, unsorted_aggregate/4 will call the % AccumulatorPred for each solution as it is obtained, rather than % first building a list of all the solutions. % :- pred unsorted_aggregate(pred(T), pred(T, U, U), U, U). :- mode unsorted_aggregate(pred(out) is multi, pred(in, in, out) is det, in, out) is cc_multi. :- mode unsorted_aggregate(pred(out) is multi, pred(in, in, out) is cc_multi, in, out) is cc_multi. :- mode unsorted_aggregate(pred(out) is multi, pred(in, di, uo) is det, di, uo) is cc_multi. :- mode unsorted_aggregate(pred(out) is multi, pred(in, di, uo) is cc_multi, di, uo) is cc_multi. :- mode unsorted_aggregate(pred(muo) is multi, pred(mdi, di, uo) is det, di, uo) is cc_multi. :- mode unsorted_aggregate(pred(out) is nondet, pred(in, di, uo) is det, di, uo) is cc_multi. :- mode unsorted_aggregate(pred(out) is nondet, pred(in, di, uo) is cc_multi, di, uo) is cc_multi. :- mode unsorted_aggregate(pred(out) is nondet, pred(in, in, out) is det, in, out) is cc_multi. :- mode unsorted_aggregate(pred(out) is nondet, pred(in, in, out) is cc_multi, in, out) is cc_multi. :- mode unsorted_aggregate(pred(muo) is nondet, pred(mdi, di, uo) is det, di, uo) is cc_multi. % unsorted_aggregate2/6 generates all the solutions to a predicate % and applies an accumulator predicate to each solution in turn. % Declaratively, the specification is as follows: % % unsorted_aggregate2(Generator, AccumulatorPred, !Acc1, !Acc2) <=> % unsorted_solutions(Generator, Solutions), % list.foldl2(AccumulatorPred, Solutions, !Acc1, !Acc2). % % Operationally, however, unsorted_aggregate2/6 will call the % AccumulatorPred for each solution as it is obtained, rather than % first building a list of all the solutions. % :- pred unsorted_aggregate2(pred(T), pred(T, U, U, V, V), U, U, V, V). :- mode unsorted_aggregate2(pred(out) is multi, pred(in, in, out, in, out) is det, in, out, in, out) is cc_multi. :- mode unsorted_aggregate2(pred(out) is multi, pred(in, in, out, in, out) is cc_multi, in, out, in, out) is cc_multi. :- mode unsorted_aggregate2(pred(out) is multi, pred(in, in, out, di, uo) is det, in, out, di, uo) is cc_multi. :- mode unsorted_aggregate2(pred(out) is multi, pred(in, in, out, di, uo) is cc_multi, in, out, di, uo) is cc_multi. :- mode unsorted_aggregate2(pred(out) is nondet, pred(in, in, out, in, out) is det, in, out, in, out) is cc_multi. :- mode unsorted_aggregate2(pred(out) is nondet, pred(in, in, out, in, out) is cc_multi, in, out, in, out) is cc_multi. :- mode unsorted_aggregate2(pred(out) is nondet, pred(in, in, out, di, uo) is det, in, out, di, uo) is cc_multi. :- mode unsorted_aggregate2(pred(out) is nondet, pred(in, in, out, di, uo) is cc_multi, in, out, di, uo) is cc_multi. % This is a generalization of unsorted_aggregate which allows the % iteration to stop before all solutions have been found. % Declaratively, the specification is as follows: % % do_while(Generator, Filter, !Acc) :- % unsorted_solutions(Generator, Solutions), % do_while_2(Solutions, Filter, !Acc). % % do_while_2([], _, !Acc). % do_while_2([X | Xs], Filter, !Acc) :- % Filter(X, More, !Acc), % ( % More = yes, % do_while_2(Xs, Filter, !Acc) % ; % More = no % ). % % Operationally, however, do_while/4 will call the Filter % predicate for each solution as it is obtained, rather than % first building a list of all the solutions. % :- pred do_while(pred(T), pred(T, bool, T2, T2), T2, T2). :- mode do_while(pred(out) is multi, pred(in, out, in, out) is det, in, out) is cc_multi. :- mode do_while(pred(out) is multi, pred(in, out, di, uo) is det, di, uo) is cc_multi. :- mode do_while(pred(out) is multi, pred(in, out, di, uo) is cc_multi, di, uo) is cc_multi. :- mode do_while(pred(out) is nondet, pred(in, out, in, out) is det, in, out) is cc_multi. :- mode do_while(pred(out) is nondet, pred(in, out, di, uo) is det, di, uo) is cc_multi. :- mode do_while(pred(out) is nondet, pred(in, out, di, uo) is cc_multi, di, uo) is cc_multi. %--------------------------------------------------% %--------------------------------------------------%
Next: sparse_bitset, Previous: set_unordlist, Up: Top [Contents]