我正在努力学习Prolog,我是一个初学者。为了理解它,我尝试编写一个函数。我有一种以这种方式定义的类型:
a(X,Y,Z).
让我们说,我的知识库是:
a(M,2,3) .
a(S,4,7) .
这里X是操作,Y,Z是将进行此操作的数字。我有一个函数f,它将执行此操作,然后如果此操作通过f的第二个参数得到结果,它将返回true。否则它将返回操作的结果。
例如,
g(M,4)
应该屈服于
6.
由于M代表乘法而6不等于4.我们假设S代表求和运算,那么
g(S,11)
由于4 + 7 = 11,应该为真。
所以,我尝试的是:
g([],0) .
g(a(M,X,Y),Z, true :- (Z =:= (X*Y) ) ) .
g(a(S,X,Y),Z, true :- (Z =:= (X+Y) ) ) .
g(a(M,X,Y),Z, (X*Y) ) .
g(a(S,X,Y),Z, (X+Y) ) .
但是当我打电话的时候 g(S,11)
我得到了
false.
虽然它应该评估为11。
当我打电话
g(S,45)
我应该得到11,但我仍然得到
false.
我非常非常初学,所以如果我错过了一些明显的事情,请不要过于苛刻,提前谢谢。
答案 0 :(得分:2)
您发布的代码存在很多问题。特别是,它不是用于定义Prolog谓词的正确语法,它使用变量(以大写字母开头)而不是我认为的原则。
例如,您的代码:
g(a(M,X,Y),Z, true :- (Z =:= (X*Y) ) ) .
简单地断言一个看起来像这样的术语,写成"规范":
g(a(M,X,Y), Z, :-(true, =:=(Z, *(X, Y))).
它是一个有效的Prolog术语,但不是用于断言谓词的Prolog语法。对于谓词,顶级仿函数必须为:-
(通常为head :- body
,或标准编写,:-(head, body)
)。在您的代码中,顶级函子g
对Prolog没有特殊意义。
您可以使用运算符本身作为操作的描述,而不是定义其他原子来表示这些操作。所以你的知识库可能是这样的:
a(*, 2, 3).
a(*, 4, 5).
a(+, 2, 4).
a(+, 4, 7).
查询可能如下所示:
g(+, 11).
然后谓词将是:
g(Operation, Result) :-
a(Operation, Operand1, Operand2),
Expression =.. [Operation, Operand1, Operand2] ,
Result #= Expression.
这里,我们查询具有可接受操作数的操作。然后,我们使用=../2
将操作和操作数统一到一个Prolog term ,它由一个仿函数(列表的第一个元素)和参数(列表的其余部分)组成。然后我们使用CLP(FD)#=
操作来正确推理整数,因为它提供了最通用的解决方案,并且评估了Expression
中术语给出的表达式。根据以上事实,这得到以下结果:
| ?- g(+, 11).
yes
| ?- g(+, R).
R = 6 ? ;
R = 11
(1 ms) yes
| ?- g(Op, 11).
Op = (+)
yes
| ?- g(Op, 6).
Op = (*) ? ;
Op = (+) ? ;
no
<小时/> 如果您确实需要为运算符使用不同的符号表示,则可以定义别名映射:
alias(add, +).
alias(mul, *).
你的事实将是:
a(mul, 2, 3).
a(mul, 4, 5).
a(add, 2, 4).
a(add, 4, 7).
然后定义:
g(Operation, Result) :-
a(Operation, Operand1, Operand2),
alias(Operation, Op),
Expression =.. [Op, Operand1, Operand2] ,
Result #= Expression.
答案 1 :(得分:1)
不幸的是,您需要了解有关Prolog的更多信息,然后才能接近您在此处尝试的操作。首先,Prolog没有函数,只有谓词。这不仅仅是一个有趣的名称,它是一个根本不同的概念。
Prolog谓词不会按照您期望的方式评估值。它们要么失败要么成功,并且在成功的情况下,它们可以将一些变量绑定到值。这看起来像是“返回”其他语言中的值,但它不一样。
让我们看一下这个版本的程序:
a(mul, 2, 3).
a(add, 4, 7).
g(mul, Z) :-
a(mul, X, Y),
Z is X * Y.
g(add, Z) :-
a(add, X, Y),
Z is X + Y.
我可以问一下,11是否是添加存储在数据库中的操作数的正确结果:
?- g(add, 11).
true.
我也可以问问它的结果是什么,没有提出我的猜测:
?- g(add, Result).
Result = 11.
但你可以不让它以错误的猜测“返回”正确的解决方案:
?- g(add, 45).
false.
这是因为任何“返回”值都会通过查询中的绑定变量来实现。但是这个查询不包含任何变量!你永远不能从看起来像这样的查询中“获取”一个值。
无论您的目标是什么,都可以在Prolog中完成,但您目前尚未走上正轨。您应该首先尝试更多地理解逻辑变量等概念,以及在程序中出现像a(mul, X, Y)
这样的术语与作为谓词参数出现的同一术语的区别。