在 prolog 中为多重集编写联合操作

Writing a union operation in prolog for multisets

在序言中有一个标准的方法来定义两个集合的并集
但我想为多重集编写联合函数。这意味着如果第一组有 [1,2] 和
第二个有 [2,3] 那么输出应该是 [1,2,2,3]。
我该如何编写这样的函数。

Prolog 中没有类型 Set。您所引用的只是列表。 union 谓词将两个列表与 assumed 唯一元素组合到一个新列表中,其中元素再次是唯一的。集合中的顺序无关紧要。当您传递 non-ordered/non-set 列表时,您会看到这一点。

% both ordered, but result is not
?- union([1, 2, 5, 6], [3, 4, 7, 8], S).
S = [1, 2, 5, 6, 3, 4, 7, 8].

% sets, not ordered
?- union([1, 2, 3], [3, 2, 4, 5], S).
S = [1, 3, 2, 4, 5].

% multisets, not ordered
?- union([1, 2, 3], [3, 2, 4, 5, 5], S).
S = [1, 3, 2, 4, 5, 5].

要创建一个多重集,即将所有元素保留在集合并集中,您可以只组合列表,同时根据需要对它们进行排序。正式地,多重集也没有排序,所以如果排序无关紧要,您可以将第二个列表附加到第一个列表,这也适用于您的示例:

?- append([1, 2, 4], [2, 3, 4, 5], S).
S = [1, 2, 4, 2, 3, 4, 5].

?- append([1, 2], [2, 3], S).
S = [1, 2, 2, 3].

如果您可以假设列表是有序的,并且您希望结果也是如此,您可以合并它们,这样可以保持顺序:

?- merge([1, 2, 4], [2, 3, 4, 5], S).
S = [1, 2, 2, 3, 4, 4, 5].

如果你不能假设列表是排序的,但你想对结果进行排序,你也可以自己处理排序,例如使用 msort:

?- append([1, 2, 3], [3, 2, 4, 5, 5], S), msort(S, S1).
S = [1, 2, 3, 3, 2, 4, 5, 5],
S1 = [1, 2, 2, 3, 3, 4, 5, 5].

排序谓词也比较多,如果比较复杂你也可以自己写一个。