jre*_*001 51 prolog iso-prolog logical-purity
可能是一个愚蠢的问题,但我无法在任何地方找到任何文档.有没有办法在prolog中执行if,例如,如果变量为0,则执行某些操作(将文本写入终端).甚至不需要else,但我找不到if的任何实现.
Mat*_*ard 85
是的,在ISO Prolog中有这样的控制结构,称为->.你这样使用它:
( condition -> then_clause ; else_clause )
Run Code Online (Sandbox Code Playgroud)
这是一个使用else-if-clauses链的示例:
( X < 0 ->
writeln('X is negative. That's weird! Failing now.'),
fail
; X =:= 0 ->
writeln('X is zero.')
; writeln('X is positive.')
)
Run Code Online (Sandbox Code Playgroud)
请注意,如果省略else子句,则条件失败将意味着整个if语句将失败.因此,我建议始终包含else子句(即使它只是true).
sto*_*tal 50
标准的prolog谓词将会这样做.
isfive(5).
Run Code Online (Sandbox Code Playgroud)
如果你用5调用它将评估为true并且如果你用其他任何东西运行它将失败(返回false).如果不相等,则使用\ =
isNotEqual(A,B):- A\=B.
Run Code Online (Sandbox Code Playgroud)
从技术上讲,它不是统一的,但它类似于不相等.
Learn Prolog Now是一个很好的学习prolog的网站.
编辑:添加另一个示例.
isEqual(A,A).
Run Code Online (Sandbox Code Playgroud)
Ann*_*poo 26
Prolog谓词'统一' -
所以,在一个必要的语言中我会写
function bazoo(integer foo)
{
if(foo == 5)
doSomething();
else
doSomeOtherThing();
}
Run Code Online (Sandbox Code Playgroud)
在Prolog我会写
bazoo(5) :- doSomething.
bazoo(Foo) :- Foo =/= 5, doSomeOtherThing.
Run Code Online (Sandbox Code Playgroud)
当你理解这两种风格时,它实际上更加清晰.
"当foo为5时,我就是特殊情况下的bazoo"
"当foo不是5时我正常情况下是bazoo
Tom*_*ard 12
我发现这对在规则中使用if语句很有帮助.
max(X,Y,Z) :-
( X =< Y
-> Z = Y
; Z = X
).
Run Code Online (Sandbox Code Playgroud)
感谢http://cs.union.edu/~striegnk/learn-prolog-now/html/node89.html
首先,让我们回顾一些经典的一阶逻辑:
" 如果 P 则 Q 否则 R"等同于"(P 和 Q)或(non_P 和 R)".
我们来看下面的具体例子:
如果
X是list的成员,[1,2]那么Xequals2elseX等于4.
如果... 我们可以匹配上面的模式(" 如果 P 然后 Q 其他 R")
P是list_member([1,2],X),non_P是non_member([1,2],X),Q是X=2,和R是X=4.为了以纯粹的方式表达列表(非)成员资格,我们定义:
list_memberd([E|Es],X) :-
( E = X
; dif(E,X),
list_memberd(Es,X)
).
non_member(Es,X) :-
maplist(dif(X),Es).
让我们看看在Prolog中表达"if-then-else"的不同方式!
(P,Q ; non_P,R)
?- (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4). X = 2 ; X = 4. ?- X=2, (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=2. X = 2 ; false. ?- (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=2. X = 2 ; false. ?- X=4, (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=4. X = 4. ?- (list_memberd([1,2],X), X=2 ; non_member([1,2],X), X=4), X=4. X = 4.
正确性得分为5/5.效率得分3/5.
(P -> Q ; R)
?- (list_memberd([1,2],X) -> X=2 ; X=4). false. % WRONG ?- X=2, (list_memberd([1,2],X) -> X=2 ; X=4), X=2. X = 2. ?- (list_memberd([1,2],X) -> X=2 ; X=4), X=2. false. % WRONG ?- X=4, (list_memberd([1,2],X) -> X=2 ; X=4), X=4. X = 4. ?- (list_memberd([1,2],X) -> X=2 ; X=4), X=4. false. % WRONG
正确性得分为2/5.效率得分2/5.
(P *-> Q ; R)
?- (list_memberd([1,2],X) *-> X=2 ; X=4). X = 2 ; false. % WRONG ?- X=2, (list_memberd([1,2],X) *-> X=2 ; X=4), X=2. X = 2 ; false. ?- (list_memberd([1,2],X) *-> X=2 ; X=4), X=2. X = 2 ; false. ?- X=4, (list_memberd([1,2],X) *-> X=2 ; X=4), X=4. X = 4. ?- (list_memberd([1,2],X) *-> X=2 ; X=4), X=4. false. % WRONG
正确性得分3/5.效率得分1/5.
(初步)摘要:
(P,Q ; non_P,R)是正确的,但需要一个独立的实现non_P.
(P -> Q ; R) 实例化不足时会丢失声明性语义.
(P *-> Q ; R)"不那么"不完整(P -> Q ; R),但仍有类似的困境.
幸运的是,还有的选择:
输入逻辑单调控制结构if_/3!
我们可以if_/3与reified list-membership谓词一起使用,memberd_t/3如下所示:
?- if_(memberd_t(X,[1,2]), X=2, X=4). X = 2 ; X = 4. ?- X=2, if_(memberd_t(X,[1,2]), X=2, X=4), X=2. X = 2. ?- if_(memberd_t(X,[1,2]), X=2, X=4), X=2. X = 2 ; false. ?- X=4, if_(memberd_t(X,[1,2]), X=2, X=4), X=4. X = 4. ?- if_(memberd_t(X,[1,2]), X=2, X=4), X=4. X = 4.
正确性得分为5/5.效率得分为4/5.
最好的办法是使用所谓cuts的符号!.
if_then_else(Condition, Action1, Action2) :- Condition, !, Action1.
if_then_else(Condition, Action1, Action2) :- Action2.
Run Code Online (Sandbox Code Playgroud)
以上是条件函数的基本结构.
举例来说,这是max函数:
max(X,Y,X):-X>Y,!.
max(X,Y,Y):-Y=<X.
Run Code Online (Sandbox Code Playgroud)
我建议阅读更多关于剪辑的文档,但总的来说它们就像断点.例如:如果第一个max函数返回一个真值,则不验证第二个函数.
PS:我对Prolog很新,但这是我发现的.
在Prolog中,如何表达if-then-else之类的内容基本上有三种不同的方法.比较他们考虑char_class/2.对于a和b班级应该ab和other所有其他条款.人们可以像这样笨拙地写这个:
char_class(a, ab).
char_class(b, ab).
char_class(X, other) :-
dif(X, a),
dif(X, b).
?- char_class(Ch, Class).
Ch = a, Class = ab
; Ch = b, Class = ab
; Class = other,
dif(Ch, a), dif(Ch, b).
Run Code Online (Sandbox Code Playgroud)
为了更紧凑地编写东西,需要一个if-then-else结构.Prolog有一个内置的:
?- ( ( Ch = a ; Ch = b ) -> Class = ab ; Class = other ).
Ch = a, Class = ab.
Run Code Online (Sandbox Code Playgroud)
虽然这个答案是合理的,但它并不完整.刚刚给出了第一个答案( Ch = a ; Ch = b ).其他答案被砍掉了.确实不是很关系.
一个更好的结构,通常被称为"软切"(不相信的名字,切割是切是切),给出稍好的结果(这是YAP):
?- ( ( Ch = a ; Ch = b ) *-> Class = ab ; Class = other ).
Ch = a, Class = ab
; Ch = b, Class = ab.
Run Code Online (Sandbox Code Playgroud)
或者,SICStus具有if/3非常相似的语义:
?- if( ( Ch = a ; Ch = b ), Class = ab , Class = other ).
Ch = a, Class = ab
; Ch = b, Class = ab.
Run Code Online (Sandbox Code Playgroud)
所以最后的答案仍然被压制.现在进入library(reif)了SICStus,YAP和SWI.安装它并说:
?- use_module(library(reif)).
?- if_( ( Ch = a ; Ch = b ), Class = ab , Class = other ).
Ch = a, Class = ab
; Ch = b, Class = ab
; Class = other,
dif(Ch, a), dif(Ch, b).
Run Code Online (Sandbox Code Playgroud)
请注意,所有这些都if_/3被编译为一个非常嵌套的if-then-else for
char_class(Ch, Class) :-
if_( ( Ch = a ; Ch = b ), Class = ab , Class = other ).
Run Code Online (Sandbox Code Playgroud)
在第6.3.4节扩展至:
char_class(A,B) :-
( A\=a
->
( A\=b
->
B=other
;
( A==b
->
B=ab
)
;
A=b,
B=ab
;
dif(A,b),
B=other
)
;
( A==a
->
B=ab
)
;
A=a,
B=ab
;
dif(A,a),
( A\=b
->
B=other
;
( A==b
->
B=ab
)
;
A=b,
B=ab
;
dif(A,b),
B=other
)
).
Run Code Online (Sandbox Code Playgroud)