我正在试验Prolog并尝试制作自己的" if-then-else
"方法,以便我不使用-> ;
方法,以进行实验。
我的目标是使它在我的代码中可以嵌套ifs和elses(如果需要)。
到目前为止,我有这个:
ifthenelse(_, G, G):- G. %no matter the condition, the goals are the same
ifthenelse(true,G,_):- G. %if
ifthenelse(false,_,G):- G. %else
我认为我的方式似乎不太正确。如何正确制作自己的ifthenelse/3
?
谢谢
答案 0 :(得分:5)
前言:与您提到的内置构造相比,您实施的内容是好多了。我将在下面更详细地讨论这一点。
关于字面问题:我认为你已经非常接近了,因为你已经可以嵌套这在某种程度上了:
?- ifthenelse(C1, ifthenelse(C2,X=1,X=2), X=3). C1 = C2, C2 = true, X = 1 ; C1 = true, C2 = false, X = 2 ; C1 = false, X = 3.
现在剩下的就是在条件中嵌套。为此,您需要一种方法 reify 条件的结果,即将真值转换为Prolog term ,您可以用符号来推理。
有关详细信息,请参阅if_/3
:Indexing dif/2
此构造保留的关键属性称为logical-purity。特别是,如果两者在逻辑上都是可能的话,不要错误地提交给一个分支!
关于纯度的注意事项:从声明的角度来看,你所实现的内容非常好,并且具有清晰的逻辑解释。以最后两个子句为例,我们可以将ifthenelse(C,G1,G2)
视为:如果 C
是true
,那么如果G1
成立则谓词成立。如果C
为false
,则G2
成立时保持d = {'a': ['1','2','3'],'b': ['1'],'c': ['1','3']}
from collections import defaultdict
d_dict = defaultdict(list)
for k,v in d.items():
for i in v:
d_dict[i].append(k)
dict(d_dict)
#{'1': ['a', 'b', 'c'], '2': ['a'], '3': ['a', 'c']}
。非常好。语义“if ... then”在任何方面都没有问题;实际上,每个单独的Horn子句都可以这种方式阅读,从右到左是一种含义。
相比之下,你提到的内置结构缺乏这样的声明性阅读。例如:
?- ( ( X = 1 ; X = 2 ) -> true ; true ). X = 1.
但另一方面:
?- X = 2, ( ( X = 1 ; X = 2 ) -> true ; true ). X = 2.
因此添加约束导致 new 解决方案。古典逻辑学家的噩梦。
你的构造避免了这样的问题,因为它不会过早地提交到任何特定的分支。这产生了一个更通用的谓词,也可以用于其他方向。例如,请参阅正确生成所有可能的解决方案:
?- ifthenelse(C, true, true). true ; C = true ; C = false.
所以,我非常鼓励你制定这个方法:正如你已经非常清楚地表明,它是你自己的'if-then-else',并且你只使用纯粹的单调构造来表达它
从心理学的角度来看,我通常更愿意为纯粹的陈述性结构提供更多空间,我之所以添加本节只是因为这些评论表达了对这些方面的真正兴趣。
答案 1 :(得分:1)
众所周知,为了避免->
并自己实现,您需要使用cut(!
)来模拟相同的行为:
if_then_else(P, Q, R) :- P, !, Q.
if_then_else(P, Q, R) :- R.
其中P
是条件Q
,然后是R
其他部分。