From a6d3f3915253aa70fac8ebd710415b892577451e Mon Sep 17 00:00:00 2001 From: Mark Thom Date: Sun, 10 Mar 2019 22:33:09 -0600 Subject: [PATCH] add ordsets library, domain.pl attributed variables example --- src/prolog/examples/domain.pl | 52 +++ src/prolog/lib/ordsets.pl | 625 ++++++++++++++++++++++++++++++++++ src/prolog/machine/compile.rs | 4 +- src/prolog/machine/mod.rs | 2 + 4 files changed, 681 insertions(+), 2 deletions(-) create mode 100644 src/prolog/examples/domain.pl create mode 100644 src/prolog/lib/ordsets.pl diff --git a/src/prolog/examples/domain.pl b/src/prolog/examples/domain.pl new file mode 100644 index 00000000..cfada79f --- /dev/null +++ b/src/prolog/examples/domain.pl @@ -0,0 +1,52 @@ +/* From the SICSTUS Prolog documentation at: +https://sicstus.sics.se/sicstus/docs/3.7.1/html/sicstus_17.html +*/ + +:- module(domain, [domain/2]). + +:- use_module(library(atts)). +:- use_module(library(ordsets), [ + ord_intersection/3, + ord_intersect/2, + list_to_ord_set/2 + ]). + +:- attribute dom/1. + +verify_attributes(Var, Other, Goals) :- + get_atts(Var, dom(Da)), !, % are we involved? + ( var(Other) -> % must be attributed then + ( get_atts(Other, dom(Db)) -> % has a domain? + ord_intersection(Da, Db, Dc), + Dc = [El|Els], % at least one element + ( Els = [] -> % exactly one element + Goals = [Other=El] % implied binding + ; Goals = [], + put_atts(Other, -dom(_)), + put_atts(Other, dom(Dc))% rescue intersection + ) + ; Goals = [], + put_atts(Other, dom(Da)) % rescue the domain + ) + ; Goals = [], + ord_intersect([Other], Da) % value in domain? + ). +verify_attributes(_, _, []). % unification triggered + % because of attributes + % in other modules + +attribute_goals(Var, domain(Var,Dom)) :- % interpretation as goal + get_atts(Var, dom(Dom)). + +domain(X, Dom) :- + var(Dom), !, + get_atts(X, dom(Dom)). +domain(X, List) :- + list_to_ord_set(List, Set), + Set = [El|Els], % at least one element + ( Els = [] -> % exactly one element + X = El % implied binding + ; put_atts(Fresh, dom(Set)), + X = Fresh % may call + % verify_attributes/3 + ). diff --git a/src/prolog/lib/ordsets.pl b/src/prolog/lib/ordsets.pl new file mode 100644 index 00000000..ff080962 --- /dev/null +++ b/src/prolog/lib/ordsets.pl @@ -0,0 +1,625 @@ +/* Author: Jan Wielemaker + E-mail: J.Wielemaker@vu.nl + WWW: http://www.swi-prolog.org + Copyright (c) 2001-2014, University of Amsterdam + VU University Amsterdam + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + +:- module(ordsets, + [ is_ordset/1, % @Term + list_to_ord_set/2, % +List, -OrdSet + ord_add_element/3, % +Set, +Element, -NewSet + ord_del_element/3, % +Set, +Element, -NewSet + ord_selectchk/3, % +Item, ?Set1, ?Set2 + ord_intersect/2, % +Set1, +Set2 (test non-empty) + ord_intersect/3, % +Set1, +Set2, -Intersection + ord_intersection/3, % +Set1, +Set2, -Intersection + ord_intersection/4, % +Set1, +Set2, -Intersection, -Diff + ord_disjoint/2, % +Set1, +Set2 + ord_subtract/3, % +Set, +Delete, -Remaining + ord_union/2, % +SetOfOrdSets, -Set + ord_union/3, % +Set1, +Set2, -Union + ord_union/4, % +Set1, +Set2, -Union, -New + ord_subset/2, % +Sub, +Super (test Sub is in Super) + % Non-Quintus extensions + ord_empty/1, % ?Set + ord_memberchk/2, % +Element, +Set, + ord_symdiff/3, % +Set1, +Set2, ?Diff + % SICSTus extensions + ord_seteq/2, % +Set1, +Set2 + ord_intersection/2 % +PowerSet, -Intersection + ]). + +:- use_module(library(lists)). + +/** Ordered set manipulation +Ordered sets are lists with unique elements sorted to the standard order +of terms (see sort/2). Exploiting ordering, many of the set operations +can be expressed in order N rather than N^2 when dealing with unordered +sets that may contain duplicates. The library(ordsets) is available in a +number of Prolog implementations. Our predicates are designed to be +compatible with common practice in the Prolog community. The +implementation is incomplete and relies partly on library(oset), an +older ordered set library distributed with SWI-Prolog. New applications +are advised to use library(ordsets). +Some of these predicates match directly to corresponding list +operations. It is advised to use the versions from this library to make +clear you are operating on ordered sets. An exception is member/2. See +ord_memberchk/2. +The ordsets library is based on the standard order of terms. This +implies it can handle all Prolog terms, including variables. Note +however, that the ordering is not stable if a term inside the set is +further instantiated. Also note that variable ordering changes if +variables in the set are unified with each other or a variable in the +set is unified with a variable that is `older' than the newest variable +in the set. In practice, this implies that it is allowed to use +member(X, OrdSet) on an ordered set that holds variables only if X is a +fresh variable. In other cases one should cease using it as an ordset +because the order it relies on may have been changed. +*/ + +%! is_ordset(@Term) is semidet. +% +% True if Term is an ordered set. All predicates in this library +% expect ordered sets as input arguments. Failing to fullfil this +% assumption results in undefined behaviour. Typically, ordered +% sets are created by predicates from this library, sort/2 or +% setof/3. + +is_ordset(Term) :- + '$skip_max_list'(_, -1, Term, Tail), Tail == [], %% is_list(Term), + is_ordset2(Term). + +is_ordset2([]). +is_ordset2([H|T]) :- + is_ordset3(T, H). + +is_ordset3([], _). +is_ordset3([H2|T], H) :- + H2 @> H, + is_ordset3(T, H2). + + +%! ord_empty(?List) is semidet. +% +% True when List is the empty ordered set. Simply unifies list +% with the empty list. Not part of Quintus. + +ord_empty([]). + + +%! ord_seteq(+Set1, +Set2) is semidet. +% +% True if Set1 and Set2 have the same elements. As both are +% canonical sorted lists, this is the same as ==/2. +% +% @compat sicstus + +ord_seteq(Set1, Set2) :- + Set1 == Set2. + + +%! list_to_ord_set(+List, -OrdSet) is det. +% +% Transform a list into an ordered set. This is the same as +% sorting the list. + +list_to_ord_set(List, Set) :- + sort(List, Set). + + +%! ord_intersect(+Set1, +Set2) is semidet. +% +% True if both ordered sets have a non-empty intersection. + +ord_intersect([H1|T1], L2) :- + ord_intersect_(L2, H1, T1). + +ord_intersect_([H2|T2], H1, T1) :- + compare(Order, H1, H2), + ord_intersect__(Order, H1, T1, H2, T2). + +ord_intersect__(<, _H1, T1, H2, T2) :- + ord_intersect_(T1, H2, T2). +ord_intersect__(=, _H1, _T1, _H2, _T2). +ord_intersect__(>, H1, T1, _H2, T2) :- + ord_intersect_(T2, H1, T1). + + +%! ord_disjoint(+Set1, +Set2) is semidet. +% +% True if Set1 and Set2 have no common elements. This is the +% negation of ord_intersect/2. + +ord_disjoint(Set1, Set2) :- + \+ ord_intersect(Set1, Set2). + + +%! ord_intersect(+Set1, +Set2, -Intersection) +% +% Intersection holds the common elements of Set1 and Set2. +% +% @deprecated Use ord_intersection/3 + +ord_intersect(Set1, Set2, Intersection) :- + oset_int(Set1, Set2, Intersection). + + +%! ord_intersection(+PowerSet, -Intersection) +% +% Intersection of a powerset. True when Intersection is an ordered +% set holding all elements common to all sets in PowerSet. +% +% @compat sicstus + +ord_intersection(PowerSet, Intersection) :- + key_by_length(PowerSet, Pairs), + keysort(Pairs, [_-S|Sorted]), + l_int(Sorted, S, Intersection). + +key_by_length([], []). +key_by_length([H|T0], [L-H|T]) :- + length(H, L), + key_by_length(T0, T). + +l_int([], S, S). +l_int([_-H|T], S0, S) :- + ord_intersection(S0, H, S1), + l_int(T, S1, S). + + +%! ord_intersection(+Set1, +Set2, -Intersection) is det. +% +% Intersection holds the common elements of Set1 and Set2. Uses +% ord_disjoint/2 if Intersection is bound to `[]` on entry. + +ord_intersection(Set1, Set2, Intersection) :- + ( Intersection == [] + -> ord_disjoint(Set1, Set2) + ; oset_int(Set1, Set2, Intersection) + ). + + +%! ord_intersection(+Set1, +Set2, ?Intersection, ?Difference) is det. +% +% Intersection and difference between two ordered sets. +% Intersection is the intersection between Set1 and Set2, while +% Difference is defined by ord_subtract(Set2, Set1, Difference). +% +% @see ord_intersection/3 and ord_subtract/3. + +ord_intersection([], L, [], L) :- !. +ord_intersection([_|_], [], [], []) :- !. +ord_intersection([H1|T1], [H2|T2], Intersection, Difference) :- + compare(Diff, H1, H2), + ord_intersection2(Diff, H1, T1, H2, T2, Intersection, Difference). + +ord_intersection2(=, H1, T1, _H2, T2, [H1|T], Difference) :- + ord_intersection(T1, T2, T, Difference). +ord_intersection2(<, _, T1, H2, T2, Intersection, Difference) :- + ord_intersection(T1, [H2|T2], Intersection, Difference). +ord_intersection2(>, H1, T1, H2, T2, Intersection, [H2|HDiff]) :- + ord_intersection([H1|T1], T2, Intersection, HDiff). + + +%! ord_add_element(+Set1, +Element, ?Set2) is det. +% +% Insert an element into the set. This is the same as +% ord_union(Set1, [Element], Set2). + +ord_add_element(Set1, Element, Set2) :- + oset_addel(Set1, Element, Set2). + + +%! ord_del_element(+Set, +Element, -NewSet) is det. +% +% Delete an element from an ordered set. This is the same as +% ord_subtract(Set, [Element], NewSet). + +ord_del_element(Set, Element, NewSet) :- + oset_delel(Set, Element, NewSet). + + +%! ord_selectchk(+Item, ?Set1, ?Set2) is semidet. +% +% Selectchk/3, specialised for ordered sets. Is true when +% select(Item, Set1, Set2) and Set1, Set2 are both sorted lists +% without duplicates. This implementation is only expected to work +% for Item ground and either Set1 or Set2 ground. The "chk" suffix +% is meant to remind you of memberchk/2, which also expects its +% first argument to be ground. ord_selectchk(X, S, T) => +% ord_memberchk(X, S) & \+ ord_memberchk(X, T). +% +% @author Richard O'Keefe + +ord_selectchk(Item, [X|Set1], [X|Set2]) :- + X @< Item, + !, + ord_selectchk(Item, Set1, Set2). +ord_selectchk(Item, [Item|Set1], Set1) :- + ( Set1 == [] + -> true + ; Set1 = [Y|_] + -> Item @< Y + ). + + +%! ord_memberchk(+Element, +OrdSet) is semidet. +% +% True if Element is a member of OrdSet, compared using ==. Note +% that _enumerating_ elements of an ordered set can be done using +% member/2. +% +% Some Prolog implementations also provide ord_member/2, with the +% same semantics as ord_memberchk/2. We believe that having a +% semidet ord_member/2 is unacceptably inconsistent with the *_chk +% convention. Portable code should use ord_memberchk/2 or +% member/2. +% +% @author Richard O'Keefe + +ord_memberchk(Item, [X1,X2,X3,X4|Xs]) :- + !, + compare(R4, Item, X4), + ( R4 = (>) -> ord_memberchk(Item, Xs) + ; R4 = (<) -> + compare(R2, Item, X2), + ( R2 = (>) -> Item == X3 + ; R2 = (<) -> Item == X1 + ;/* R2 = (=), Item == X2 */ true + ) + ;/* R4 = (=) */ true + ). +ord_memberchk(Item, [X1,X2|Xs]) :- + !, + compare(R2, Item, X2), + ( R2 = (>) -> ord_memberchk(Item, Xs) + ; R2 = (<) -> Item == X1 + ;/* R2 = (=) */ true + ). +ord_memberchk(Item, [X1]) :- + Item == X1. + + +%! ord_subset(+Sub, +Super) is semidet. +% +% Is true if all elements of Sub are in Super + +ord_subset([], _). +ord_subset([H1|T1], [H2|T2]) :- + compare(Order, H1, H2), + ord_subset_(Order, H1, T1, T2). + +ord_subset_(>, H1, T1, [H2|T2]) :- + compare(Order, H1, H2), + ord_subset_(Order, H1, T1, T2). +ord_subset_(=, _, T1, T2) :- + ord_subset(T1, T2). + + +%! ord_subtract(+InOSet, +NotInOSet, -Diff) is det. +% +% Diff is the set holding all elements of InOSet that are not in +% NotInOSet. + +ord_subtract(InOSet, NotInOSet, Diff) :- + oset_diff(InOSet, NotInOSet, Diff). + + +%! ord_union(+SetOfSets, -Union) is det. +% +% True if Union is the union of all elements in the superset +% SetOfSets. Each member of SetOfSets must be an ordered set, the +% sets need not be ordered in any way. +% +% @author Copied from YAP, probably originally by Richard O'Keefe. + +ord_union([], []). +ord_union([Set|Sets], Union) :- + length([Set|Sets], NumberOfSets), + ord_union_all(NumberOfSets, [Set|Sets], Union, []). + +ord_union_all(N, Sets0, Union, Sets) :- + ( N =:= 1 + -> Sets0 = [Union|Sets] + ; N =:= 2 + -> Sets0 = [Set1,Set2|Sets], + ord_union(Set1,Set2,Union) + ; A is N>>1, + Z is N-A, + ord_union_all(A, Sets0, X, Sets1), + ord_union_all(Z, Sets1, Y, Sets), + ord_union(X, Y, Union) + ). + + +%! ord_union(+Set1, +Set2, ?Union) is det. +% +% Union is the union of Set1 and Set2 + +ord_union(Set1, Set2, Union) :- + oset_union(Set1, Set2, Union). + + +%! ord_union(+Set1, +Set2, -Union, -New) is det. +% +% True iff ord_union(Set1, Set2, Union) and +% ord_subtract(Set2, Set1, New). + +ord_union([], Set2, Set2, Set2). +ord_union([H|T], Set2, Union, New) :- + ord_union_1(Set2, H, T, Union, New). + +ord_union_1([], H, T, [H|T], []). +ord_union_1([H2|T2], H, T, Union, New) :- + compare(Order, H, H2), + ord_union(Order, H, T, H2, T2, Union, New). + +ord_union(<, H, T, H2, T2, [H|Union], New) :- + ord_union_2(T, H2, T2, Union, New). +ord_union(>, H, T, H2, T2, [H2|Union], [H2|New]) :- + ord_union_1(T2, H, T, Union, New). +ord_union(=, H, T, _, T2, [H|Union], New) :- + ord_union(T, T2, Union, New). + +ord_union_2([], H2, T2, [H2|T2], [H2|T2]). +ord_union_2([H|T], H2, T2, Union, New) :- + compare(Order, H, H2), + ord_union(Order, H, T, H2, T2, Union, New). + + +%! ord_symdiff(+Set1, +Set2, ?Difference) is det. +% +% Is true when Difference is the symmetric difference of Set1 and +% Set2. I.e., Difference contains all elements that are not in the +% intersection of Set1 and Set2. The semantics is the same as the +% sequence below (but the actual implementation requires only a +% single scan). +% +% == +% ord_union(Set1, Set2, Union), +% ord_intersection(Set1, Set2, Intersection), +% ord_subtract(Union, Intersection, Difference). +% == +% +% For example: +% +% == +% ?- ord_symdiff([1,2], [2,3], X). +% X = [1,3]. +% == + +ord_symdiff([], Set2, Set2). +ord_symdiff([H1|T1], Set2, Difference) :- + ord_symdiff(Set2, H1, T1, Difference). + +ord_symdiff([], H1, T1, [H1|T1]). +ord_symdiff([H2|T2], H1, T1, Difference) :- + compare(Order, H1, H2), + ord_symdiff(Order, H1, T1, H2, T2, Difference). + +ord_symdiff(<, H1, Set1, H2, T2, [H1|Difference]) :- + ord_symdiff(Set1, H2, T2, Difference). +ord_symdiff(=, _, T1, _, T2, Difference) :- + ord_symdiff(T1, T2, Difference). +ord_symdiff(>, H1, T1, H2, Set2, [H2|Difference]) :- + ord_symdiff(Set2, H1, T1, Difference). + +/* The osets library on which ordsets depends. + + Author: Jon Jagger + E-mail: J.R.Jagger@shu.ac.uk + Copyright (c) 1993-2011, Jon Jagger + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. +*/ + + +/** Ordered set manipulation + +This library defines set operations on sets represented as ordered +lists. + +@author Jon Jagger +@deprecated Use the de-facto library ordsets.pl +*/ + + +%% oset_is(+OSet) +% check that OSet in correct format (standard order) + +oset_is(-) :- !, fail. % var filter +oset_is([]). +oset_is([H|T]) :- + oset_is(T, H). + +oset_is(-, _) :- !, fail. % var filter +oset_is([], _H). +oset_is([H|T], H0) :- + H0 @< H, % use standard order + oset_is(T, H). + + + +%% oset_union(+OSet1, +OSet2, -Union). + +oset_union([], Union, Union). +oset_union([H1|T1], L2, Union) :- + union2(L2, H1, T1, Union). + +union2([], H1, T1, [H1|T1]). +union2([H2|T2], H1, T1, Union) :- + compare(Order, H1, H2), + union3(Order, H1, T1, H2, T2, Union). + +union3(<, H1, T1, H2, T2, [H1|Union]) :- + union2(T1, H2, T2, Union). +union3(=, H1, T1, _H2, T2, [H1|Union]) :- + oset_union(T1, T2, Union). +union3(>, H1, T1, H2, T2, [H2|Union]) :- + union2(T2, H1, T1, Union). + + +%% oset_int(+OSet1, +OSet2, -Int) +% ordered set intersection + +oset_int([], _Int, []). +oset_int([H1|T1], L2, Int) :- + isect2(L2, H1, T1, Int). + +isect2([], _H1, _T1, []). +isect2([H2|T2], H1, T1, Int) :- + compare(Order, H1, H2), + isect3(Order, H1, T1, H2, T2, Int). + +isect3(<, _H1, T1, H2, T2, Int) :- + isect2(T1, H2, T2, Int). +isect3(=, H1, T1, _H2, T2, [H1|Int]) :- + oset_int(T1, T2, Int). +isect3(>, H1, T1, _H2, T2, Int) :- + isect2(T2, H1, T1, Int). + + +%% oset_diff(+InOSet, +NotInOSet, -Diff) +% ordered set difference + +oset_diff([], _Not, []). +oset_diff([H1|T1], L2, Diff) :- + diff21(L2, H1, T1, Diff). + +diff21([], H1, T1, [H1|T1]). +diff21([H2|T2], H1, T1, Diff) :- + compare(Order, H1, H2), + diff3(Order, H1, T1, H2, T2, Diff). + +diff12([], _H2, _T2, []). +diff12([H1|T1], H2, T2, Diff) :- + compare(Order, H1, H2), + diff3(Order, H1, T1, H2, T2, Diff). + +diff3(<, H1, T1, H2, T2, [H1|Diff]) :- + diff12(T1, H2, T2, Diff). +diff3(=, _H1, T1, _H2, T2, Diff) :- + oset_diff(T1, T2, Diff). +diff3(>, H1, T1, _H2, T2, Diff) :- + diff21(T2, H1, T1, Diff). + + +%% oset_dunion(+SetofSets, -DUnion) +% distributed union + +oset_dunion([], []). +oset_dunion([H|T], DUnion) :- + oset_dunion(T, H, DUnion). + +oset_dunion([], DUnion, DUnion). +oset_dunion([H|T], DUnion0, DUnion) :- + oset_union(H, DUnion0, DUnion1), + oset_dunion(T, DUnion1, DUnion). + + +%% oset_dint(+SetofSets, -DInt) +% distributed intersection + +oset_dint([], []). +oset_dint([H|T], DInt) :- + dint(T, H, DInt). + +dint([], DInt, DInt). +dint([H|T], DInt0, DInt) :- + oset_int(H, DInt0, DInt1), + dint(T, DInt1, DInt). + + +%! oset_power(+Set, -PSet) +% +% True when PSet is the powerset of Set. That is, Pset is a set of +% all subsets of Set, where each subset is a proper ordered set. + +oset_power(S, PSet) :- + reverse(S, R), + pset(R, [[]], PSet0), + sort(PSet0, PSet). + + +% The powerset of a set is the powerset of a set of one smaller, +% together with the set of one smaller where each subset is extended +% with the new element. Note that this produces the elements of the set +% in reverse order. Hence the reverse in oset_power/2. + +pset([], PSet, PSet). +pset([H|T], PSet0, PSet) :- + happ(PSet0, H, PSet1), + pset(T, PSet1, PSet). + +happ([], _, []). +happ([S|Ss], H, [[H|S],S|Rest]) :- + happ(Ss, H, Rest). + +%% oset_addel(+Set, +El, -Add) +% ordered set element addition + +oset_addel([], El, [El]). +oset_addel([H|T], El, Add) :- + compare(Order, H, El), + addel(Order, H, T, El, Add). + +addel(<, H, T, El, [H|Add]) :- + oset_addel(T, El, Add). +addel(=, H, T, _El, [H|T]). +addel(>, H, T, El, [El,H|T]). + +%% oset_delel(+Set, +El, -Del) +% ordered set element deletion + +oset_delel([], _El, []). +oset_delel([H|T], El, Del) :- + compare(Order, H, El), + delel(Order, H, T, El, Del). + +delel(<, H, T, El, [H|Del]) :- + oset_delel(T, El, Del). +delel(=, _H, T, _El, T). +delel(>, H, T, _El, [H|T]). diff --git a/src/prolog/machine/compile.rs b/src/prolog/machine/compile.rs index 9761b6ee..b2bb3914 100644 --- a/src/prolog/machine/compile.rs +++ b/src/prolog/machine/compile.rs @@ -192,8 +192,8 @@ fn add_hooks_to_mockup(code_repo: &mut CodeRepo, hook: CompileTimeHook, let preds = code_repo.term_dir.entry(key.clone()) .or_insert((Predicate::new(), VecDeque::from(vec![]))); - (preds.0).0.extend((expansions.0).0.iter().cloned()); - preds.1.extend(expansions.1.iter().cloned()); + (preds.0).0.extend((expansions.0).0.into_iter()); + preds.1.extend(expansions.1.into_iter()); } fn setup_module_expansions(wam: &mut Machine, module_name: ClauseName) diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 3b57e7af..31ff4d72 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -154,6 +154,7 @@ static DIF: &str = include_str!("../lib/dif.pl"); static FREEZE: &str = include_str!("../lib/freeze.pl"); static REIF: &str = include_str!("../lib/reif.pl"); static ASSOC: &str = include_str!("../lib/assoc.pl"); +static ORDSETS: &str = include_str!("../lib/ordsets.pl"); impl Machine { fn compile_special_forms(&mut self) { @@ -186,6 +187,7 @@ impl Machine { compile_user_module(self, FREEZE.as_bytes()); compile_user_module(self, REIF.as_bytes()); compile_user_module(self, ASSOC.as_bytes()); + compile_user_module(self, ORDSETS.as_bytes()); } pub fn new() -> Self { -- 2.54.0