From 5d8a6da0f070bbf08fffca7e2d74228c20f7fd5d Mon Sep 17 00:00:00 2001 From: Danielle Church Date: Thu, 26 Aug 2021 16:43:29 -0400 Subject: [PATCH] ADDED: ord_difference/4, ord_partition/5 These operations (split diff, diff+intersection) felt like they were missing in the ordsets library. ord_partition/5, in particular, is a generalization of a number of different ordsets predicates; if it were not for the fact that it potentially uses more memory than simpler predicates like ord_intersection/3, I'd suggest that the others get rewritten to use ord_partition/5 as a foundation. It also brings a potential VM optimization to light: being able to propagate the "don't-care"-ness of a `_` argument into the called predicate could allow a complex, multi-modal predicate like this to be used without penalty. --- library/ordsets.pl | 43 +++++++++++++++++++++++++++++++++++++++++++ packages/binformat | 1 + 2 files changed, 44 insertions(+) create mode 160000 packages/binformat diff --git a/library/ordsets.pl b/library/ordsets.pl index d227b24f3f..729d05f75f 100644 --- a/library/ordsets.pl +++ b/library/ordsets.pl @@ -54,6 +54,8 @@ ord_empty/1, % ?Set ord_memberchk/2, % +Element, +Set, ord_symdiff/3, % +Set1, +Set2, ?Diff + ord_difference/4, % +Set1, +Set2, ?Diff1, ?Diff2 + ord_partition/5, % +Set1, +Set2, ?Diff1, ?Intersection, ?Diff2 % SICSTus extensions ord_seteq/2, % +Set1, +Set2 ord_intersection/2 % +PowerSet, -Intersection @@ -503,3 +505,44 @@ ord_symdiff(>, H1, T1, H2, Set2, [H2|Difference]) :- ord_symdiff(Set2, H1, T1, Difference). +%! ord_difference(+Set1, +Set2, ?Diff1, ?Diff2) is det. +% +% Diff1 is the set holding all elements of Set1 that are not in +% Set2, and Diff2 is has the elements of Set2 not in Set1. +% This is the same as ord_partition(Set1, Set2, Diff1, _, Diff2). + +ord_difference(Set1, Set2, Diff1, Diff2) :- + ord_partition(Set1, Set2, Diff1, _, Diff2). + +%! ord_partition(+Set1, +Set2, ?Diff1, ?Intersection, ?Diff2) is det. +% +% Is true when Intersection is the set holding all elements common +% to Set1 and Set2, Diff1 has the elements unique to Set1, and +% Diff2 has the elements unique to Set2. This is semantically +% equivalent to: +% +% == +% ord_intersection(Set1, Set2, Intersection), +% ord_subtract(Set1, Set2, Diff1), +% ord_subtract(Set2, Set1, Diff2). +% == +ord_partition([], Set2, [], [], Set2). +ord_partition([H1|T1], Set2, Diff1, Intersection, Diff2) :- + ord_partition21(Set2, H1, T1, Diff1, Intersection, Diff2). + +ord_partition21([], H1, T1, [H1|T1], [], []). +ord_partition21([H2|T2], H1, T1, Diff1, Intersection, Diff2) :- + compare(Order, H1, H2), + ord_partition(Order, H1, T1, H2, T2, Diff1, Intersection, Diff2). + +ord_partition12([], H2, T2, [], [], [H2|T2]). +ord_partition12([H1|T1], H2, T2, Diff1, Intersection, Diff2) :- + compare(Order, H1, H2), + ord_partition(Order, H1, T1, H2, T2, Diff1, Intersection, Diff2). + +ord_partition(<, H1, T1, H2, T2, [H1|Diff1], Intersection, Diff2) :- + ord_partition12(T1, H2, T2, Diff1, Intersection, Diff2). +ord_partition(=, H1, T1, _H2, T2, Diff1, [H1|Intersection], Diff2) :- + ord_partition(T1, T2, Diff1, Intersection, Diff2). +ord_partition(>, H1, T1, H2, T2, Diff1, Intersection, [H2|Diff2]) :- + ord_partition21(T2, H1, T1, Diff1, Intersection, Diff2). \ No newline at end of file diff --git a/packages/binformat b/packages/binformat new file mode 160000 index 0000000000..64ad52e64a --- /dev/null +++ b/packages/binformat @@ -0,0 +1 @@ +Subproject commit 64ad52e64a0b02b6e30ee4e684c79fa309dd7de8