- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下代码:
neighbor(C1, C2, [C1, C2|L]).
neighbor(C1, C2, [C2, C1|L]).
neighbor(C1, C2, [H|L]) :- neighbor(C1, C2, L).
not_neighbors(C5, C2, E, R) :-
not_neighbor(C5, C2, E).
not_neighbors(C5, C2, E, R) :-
not_neighbor(C5, C2, R).
/* THIS DON'T WORK */
not_neighbor(C5, C2, E) :-
\+ neighbor(C5, C2, E).
或者:
same_position(I, J, [I|U], [J|V]).
same_position(I, J, [M|U], [N|V]) :-
I \== M, % optimisation
J \== N, % optimisation
same_position(I, J, U, V).
/* THIS DON'T WORK */
not_under(C4, C1, R, E) :-
\+ same_position(C4, C1, R, E).
我知道问题在于否定,例如我想得到 same_position
相反的结果。
M。 @CapelliC 建议我使用 dif/2
但我不知道如何将其应用到我的具体示例中。
最佳答案
让我们首先从逻辑上思考列表中“邻居”的含义:在什么情况下 A
和 B
是列表中的相邻元素?
答案:如果列表的形式为 [...,X,Y,...]
并且至少满足以下其中一项:
A = X
和 B = Y
A = Y
和 B = X
。用逻辑术语来说:( A = X
∧ B = Y
) ∨ ( A = Y
∧ B = X
)。
我们想要陈述它的相反,即否定公式:
← ( ( A = X
∧ B = Y
) ∨ ( A = Y
∧ B = X
) ) ≡
� ( A = X
∧ B = Y
) ∧ � ( A = Y
∧ B = X
) � � �
≡(ØA = X
∨ØB = Y
)∧(ØA = Y
∨ØB = X
)Ø
≡ ( A
≠ X
∨ B
≠ Y
) ∧ ( A
≠ Y
∨ B
≠ X
)
谁会想到德摩根定律有任何实际应用,对吧?
为了在 Prolog 中声明 X
≠ Y
,我们使用强大的 dif/2
约束,正如 @CapelliC 已经建议的那样。 dif/2
为 true 当且仅当其参数是不同术语。它是一个纯谓词,并且在所有方向上都能正确工作。如果您的 Prolog 系统尚未提供它,请务必让您的供应商知道您需要它!在此之前,如有必要,您可以使用 iso_dif/2
来近似它。
在 Prolog 中,上面的内容就变成了:
( dif(A, X) ; dif(B, Y) ), ( dif(A, Y) ; dif(B, X) )
because (',')/2
denotes conjunction, and (;)/2
denotes disjunction.
So we have:
not_neighbours(_, _, []).not_neighbours(_, _, [_]).not_neighbours(A, B, [X,Y|Rest]) :- ( dif(A, X) ; dif(B, Y) ), ( dif(A, Y) ; dif(B, X) ), not_neighbours(A, B, [Y|Rest]).
A few test cases make us more confident about the predicate's correctness:
?- not_neighbours(a, b, [a,b]).false.?- not_neighbours(A, B, [A,B]).false.?- not_neighbours(A, B, [_,A,B|_]).false.?- not_neighbours(A, B, [_,B,A|_]).false.?- not_neighbours(a, b, [_,a,c,_]).true .
Note that this definition works correctly also if all arguments are variables, which we call the most general case.
A drawback of this solution is that (;)/2
creates many alternatives, and many of them do not matter at all. We can make this significantly more efficient by another algebraic equivalence that lets us get rid of unneeded alternatives:
¬ A ∨ B ≡ A → B
So, in our case, we can write (¬ A = X
∨ ¬ B = Y
) as A = X
→B
≠Y
.
We can express implication in Prolog with the powerful if_/3
meta-predicate:
impl(A, B) :- if_(A, B, true).
因此我们可以以声明方式等效地将我们的解决方案编写为:
not_neighbours(_, _, []).not_neighbours(_, _, [_]).not_neighbours(A, B, [X,Y|Rest]) :- impl(A=X, dif(B, Y)), impl(B=X, dif(A, Y)), not_neighbours(A, B, [Y|Rest]).
Sample query:
?- not_neighbours(a, b, [x,y]).true ;false.
And a more general case:
?- not_neighbours(a, b, [X,Y]).X = a,dif(Y, b) ;X = b,dif(Y, a) ;dif(X, b),dif(X, a) ;false.
You can use this predicate for checking and generating answers. Try for example iterative deepening to fairly enumerate all answers:
?- length(Ls, _), not_neighbours(A, B, Ls).
值得注意的是,纯粹的逻辑推理使我们得到了一个通用的且高效的 Prolog 程序。
dif/2
乍一看可能对您来说很不寻常,因为它出现在第一个 Prolog 系统中,然后一度被一些供应商忽略。如今,dif/2
在越来越多的实现中(再次)成为可用的,作为一个重要的内置谓词,它允许您以声明方式声明两个术语是不同的。使用 dif/2
可以避免其不纯的替代方案通常在 Prolog 类(class)中引起的巨大困惑。
关于序言 : get the opposite result,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39336904/
欢迎!这个系列的博文会带你使用golang语言来编写一个你自己的文本编辑器。 首先想说说写这个系列文章的动机。 其实作为校招生加入某头部互联网大厂一转眼已经快4年了。可以说该大厂算是比较早的用g
我想在序言中向数据库添加文本。就像是 adding :- tell('a.txt'), write('abc'), told. 但不会覆盖a.txt。我试过像这样使用append: append('a
我正在开发一款名为“狼山羊白菜”的益智游戏。编程语言是 Prolog。 change(e,w). change(w,e). move([X,X,Goat,Cabbage],wolf,[Y,Y,Goat
我对 Prolog 很陌生。 我有这样的图: edge(a,e). edge(e,f). edge(f,d). edge(d,a). 我将传递闭包定义为: p(X,Y) :- edge(X,Y). t
我想知道如何使用我拥有的元素获得一个漂亮的外观列表!我一直在尝试查找有关此内容的内容,但我发现的实际示例似乎都没有实际工作 这是我在网上找到的一种方法: create_list(Item, List,
我有一个使用约束用Sicstus Prolog编写的程序。 我的目标是使用labeling/2和其他方法来获取变量的随机实例化。 例子: X #> 2, Y #= 2*X, Z #<10 如果我用 L
我想知道,我知道你可以使用 assert添加事实或规则或其他任何内容,如果您已将谓词声明为 -:dynamic ,但这仅允许所做的更改仅保留在该 session 中,例如如果关闭 Prolog 窗口,
关于如何检索列表中重复次数最多的元素的任何想法。 即如下所示, ?- maxRepeated([1,2,7,3,6,1,2,2,3],M). M = 2. 最佳答案 我非常喜欢 Prolog 的关系功
my_reverse(L1,L2) :- my_rev2(L1,L2,[]). my_rev2([],L2,L2). my_rev2([X|Xs],L2,Acc) :- my_rev2(Xs,L2,[
我正在编写一个序言程序,该程序将检查两个数学表达式是否实际上相同。例如,如果我的数学表达式目标是:(a + b) + c,则以下任何表达式都被视为相同: (a+b)+c a+(b+c) (b+a)+c
我必须编写一个计算魔法矩阵的程序,我已经编写了我的代码并且它可以工作,但是我的排列非常慢。我需要一个更快的人可以帮助我请 这是代码: diabolico([A,B,C,D,E,F,G,H,I,J,K,
关于如何检索列表中重复次数最多的元素的任何想法。 即如下所示, ?- maxRepeated([1,2,7,3,6,1,2,2,3],M). M = 2. 最佳答案 我非常喜欢 Prolog 的关系功
我正在关注一个要求定义对称关系的 Prolog 教程。 例如,假设您在知识库中有以下事实: colleague(john,bob). 您还希望 colleague(bob,john) 是真实的,对于所
笔者从大学时期就开始接触的前端,在刚去实习的时候就被导师安排去做内网的一个小富文本工具。之后从毕业后干的第一份工作游戏客户端,到现在做着可视化相关的前端工作,都有在做富文本相关的内容。可以说是和 富文
我有一个对列表,想找到具有相应第一个值的元素。 ?- findconn1(9, [(9,[23,33]),(42,[21,322])], R). 所以在这种情况下,我希望结果是 (9,[23,23])
我试图让我的 ARM 围绕一些基本的序言,但在这个过程中有点挣扎。具体来说 - 我试图通过一个项目列表并将其逐项复制到一个新列表中。我可以让它反转,但我发现在不反转的情况下这样做会更棘手。 我一直在尝
当我的 friend 在学校开始学习 Prolog 时,我取笑他学习了无用的语言。然而,他向我展示了一些我什至不知道可能的东西;我想知道这个技术是从哪里来的。 技术是这样的: permutation(
我有下一条规则 % Signature: natural_number(N)/1 % Purpose: N is a natural number. natural_number(0). natura
我在理解为什么我在 prolog 中的代码根据我放置规则的顺序做某事时遇到了一些麻烦。 这是我的数据库: parent(tom, bob). parent(tom, liz). parent(mary
我正在尝试学习一些关于 swi-prolog 的知识(除了基本的、无用的程序)。 谁能解释(也许用伪代码)这个数独求解器和相关函数在做什么?如果您需要更多引用,可以在 swi-prolog 的 CLP
我是一名优秀的程序员,十分优秀!