我试图定义一个谓词"删除(L1,L2,L3)"当L3等于L2减去L1中包含的任何这些元素时,这是有效的。例如。删除([1],[1,2,3],X)=>将统一为X = [2,3]。我的代码如下:
isNonElement(_, []).
isNonElement(X, [Y|Z]) :- X \= Y, isNonElement(X,Z).
delete(_, [], []).
delete(Y, [X|W], Z) :- \+(isNonElement(X, Y)), delete(Y, W, Z).
delete(Y, [X|W], [X|Z]) :- isNonElement(X, Y), delete(Y, W, Z).
然而,它似乎不适用于每个测试用例。任何人都可以帮我解决我的代码可能出错的问题吗?
提前致谢!
祝你好运, Skyfe。
P.S。我无法告诉我的谓词无法正常工作的案例,因为它已经被学校系统测试过,而系统并没有告诉我哪些测试用例失败了。
答案 0 :(得分:3)
你非常接近!
剩下的一个问题是,您正在对不承认此类阅读的谓词应用完美合理的逻辑推理。如果您只是简单地应用以下非常直接的更改,那么您的代码将完全按预期工作:
(\=)/2
,请使用dif/2
\+(isNonElement(X, Y))
,只需写下:member(X, Y)
。第一个更改始终是可取的:它通常会使您的程序在更多方向上可用。第二个改变是通过使用纯谓词来避免使用不纯的否定。
总的来说,我们现在有:
isNonElement(_, []). isNonElement(X, [Y|Z]) :- dif(X, Y), isNonElement(X,Z). delete(_, [], []). delete(Y, [X|W], Z) :- member(X, Y), delete(Y, W, Z). delete(Y, [X|W], [X|Z]) :- isNonElement(X, Y), delete(Y, W, Z).
现在检查一下:首先,你的测试用例:
?- delete([1], [1,2,3], X). X = [2, 3] ; false.
按预期工作!
其次,L2
变量的案例:
?- delete([], L2, []). L2 = [] ; false.
这似乎也很不错。
第三,另一个变量:
?- delete([X], [1,2,3], Ls3). X = 1, Ls3 = [2, 3] ; X = 2, Ls3 = [1, 3] ; X = 3, Ls3 = [1, 2] ; Ls3 = [1, 2, 3], dif(X, 3), dif(X, 2), dif(X, 1) ; false.
现在请注意X
的不同可能性以及dif/2
在答案中使用X
表示member/2
必须与某些整数不同在这种情况下
使用不纯的谓词排除了这种更一般的用途,您的评分系统也可以尝试这种情况。
请注意,您自己可以轻松实现delete/3
。这是最直接的关系之一。但是,请注意IEntityService<T>
非常有名:命令式总是暗示一个特定的使用方向,但我们在这里考虑的关系也承认了许多其他使用模式!