由于CLP(set)似乎在“立即”路线图中已经停留了7年之久,而且还在不断增加,所以我试图做一个不完整,效率低下的替代方案,以至少能够反映集合成员资格的语义。主要思想是检查类成员函数的成员资格,并使用CLP(fd)强制执行整数列表中的顺序,因此“集合”列表的排列不会使可能的解决方案数量呈指数级增长。我提出了以下建议:
(defne set-membero [elt set both]
([elt set both]
(== set both)
(membero elt set))
([elt [] [elt]])
([elt [x . smallrest] [x . bigrest]]
(fd/in elt x Integer/MIN_VALUE Integer/MAX_VALUE)
(fd/< x elt)
(set-membero elt smallrest bigrest))
([elt [x . _] [elt . set]]
(fd/in elt x Integer/MIN_VALUE Integer/MAX_VALUE)
(fd/< elt x)))
预期用途类似于以下内容:
(run 2 [q] (set-membero 1 [2 3] q)) "=> ((1 2 3))" ; adds non existing members as membero
(run 2 [q] (set-membero 1 [1 2] q)) "=> ((1 2))" ; but does not add existing elements
(run 2 [q] (set-membero q [1 2] [1 2 3])) "=> (3)" ; substracts sets as expected
(run 2 [q] (set-membero q [1] [1 2 3])) "=> ()" ; remember it is not set-difference!
(run 2 [q] (set-membero 1 q [1 2])) "=> ((1 2))" ; extracts elements as expected
(run 2 [q] (set-membero 2 [3 1] q)) "=> ()" ; fails with non-compliant "sets" (unordered)
但是我一直坚持为什么会发生这种情况:
(run 2 [q] (set-membero 4 [3] q))
=> () ; expected ([3 4])
这种简单的情况有效:
(run 2 [q] (set-membero 4 [] q))
=> ([4]) ; as expected
不是应该通过第三条defne减少规则将(set-membero 4 [3] q)
减少到(set-membero 4 [] q)
吗?