我需要一个解决方案来删除列表中包含多个匹配项的元素。 我在haskell做过,但我没有任何想法如何在Prolog中解释它 例如[1,2,2,2,4,4,5,6,6,6,6] - > [1,2,2,2,5]
Haskell中的代码:
import Data.List
count e list = length $ filter (==e) list
isnotEven = (== 1) . (`mod` 2)
removeUnique :: [Int] -> [Int]
removeUnique list = filter (\x -> isnotEven (count x list) ) list
答案 0 :(得分:3)
以下是您的Haskell代码。
:- use_module(reif).
oddcount_t(List, E, T) :- % reified: last argument is truth value
tfilter(=(E), List, Eqs),
length(Eqs, Nr),
M is Nr mod 2,
=(M, 1, T).
removeevenocc(List, RList) :-
tfilter(oddcount_t(List), List, RList).
?- removeevenocc([1,2,2,2,4,4,5,6,6,6,6], R).
R = [1,2,2,2,5].
?- removeevenocc([1,X], R).
X = 1,
R = []
; R = [1, X],
dif(X, 1).
请注意最后一个问题。这里没有完全给出列表:第二个元素未知。因此,Prolog为X
的所有可能的值生成答案! X
为1,结果列表为空,或X
不为1,则列表保持不变。
答案 1 :(得分:0)
此代码段使用了一些可用的库(聚合,列表,yall),以及一些内置函数,如setof / 3和(=:=)/ 2:
?- L=[1,2,2,2,4,4,5,6,6,6,6],
| setof(K,C^(aggregate(count,member(K,L),C),0=:=C mod 2),Ds),
| foldl([E,X,Y]>>delete(X,E,Y),Ds,L,R).
L = [1, 2, 2, 2, 4, 4, 5, 6, 6|...],
Ds = [4, 6],
R = [1, 2, 2, 2, 5].
修改的
考虑setof / 3行为(我的错误:如果没有解决方案,setof / 3会失败),可能的更正:
?- L=[1],
(setof(K,C^(aggregate(count,member(K,L),C),0=:=C mod 2),Ds);Ds=[]),
foldl([E,X,Y]>>delete(X,E,Y),Ds,L,R).
L = R, R = [1],
Ds = [].
现在还有一个选择点,正确的语法可能是
?- L=[1],
(setof(K,C^(aggregate(count,member(K,L),C),0=:=C mod 2),Ds)->true;Ds=[]),
foldl([E,X,Y]>>delete(X,E,Y),Ds,L,R).
L = R, R = [1],
Ds = [].