Prolog将文本转换为数字并执行算术运算
我第一次在prolog中工作。 我正在尝试转换文本中的操作。 比如,, 三加三等于六 应该返回true。 我试过这个。 我在最后一行遇到错误,当我尝试添加(一,一,二)时,它返回false而不是trueProlog将文本转换为数字并执行算术运算,prolog,Prolog,我第一次在prolog中工作。 我正在尝试转换文本中的操作。 比如,, 三加三等于六 应该返回true。 我试过这个。 我在最后一行遇到错误,当我尝试添加(一,一,二)时,它返回false而不是true numericValue(ONE, 1). numericValue(TWO, 2). numericValue(THREE, 3). numericValue(FOUR, 4). numericValue(FIVE, 5). numericValue(SIX, 6). numericValue
numericValue(ONE, 1).
numericValue(TWO, 2).
numericValue(THREE, 3).
numericValue(FOUR, 4).
numericValue(FIVE, 5).
numericValue(SIX, 6).
numericValue(SEVEN, 7).
numericValue(EIGHT, 8).
numericValue(ZERO, 0).
numericValue(NINE, 9).
add(num1,num2,num3):-
numericValue(num1,a),
numericValue(num2,b),
numericValue(num3,c),
(c =:= a+b -> true ; false).
istBiggerThen(XinEng,YinEng) :-
numericValue(XinEng, X),
numericValue(YinEng, Y),
( X < Y -> true ; false).
A + B = C :- add(A,B,C).
l
iterals(小写)与V
ariabls(大写):
正如@潜伏者所指出的,你把你的原子和变量搞混了。所以你的事实应该是这样的:
text_to_number(one, 1).
text_to_number(two, 2).
text_to_number(three, 3).
%% etc...
虽然您的规则需要使用变量,例如:
add(A_Text, B_Text, C_Text) :-
text_to_number(A_Text, A_Num),
text_to_number(B_Text, B_Num),
C_Num is A_Num + B_Num,
text_to_number(C_Text, C_Num).
bigger_than(A_Text, B_Text) :-
text_to_number(A_Text, A_Num),
text_to_number(B_Text, B_Num),
A_Num > B_Num.
add(ONE,ONE,TWO)
结果为false的原因是add/3
的原始规则仅定义原子num1、num2、num3、a、b、c之间的关系。查询add(一,一,二)
Prolog尝试将变量与规则头部的原子统一起来,即add(num1,num2,num3)
。因为查询的第一个和第二个参数是ONE
,所以这种统一是不可能的,因为ONE=ONE
但是num1\=num2
。由于add/3
没有进一步的规则或事实,因此查询只返回false
使用模式(|条件|->真;假):
子句主体中的语句(即:-
运算符右侧的语句)被计算为true或false,因此您几乎不需要使用模式(| Condition |->true;false)
。例如,C_Num是A_Num+B_Num
为真,如果C_Num
可以与A_Num
和B_Num
之和统一,否则为假,在这种情况下,Prolog将开始回溯
使用=:=/2
与是/2
:
=:=/2
检查第一个参数与第二个参数的值是否相等,第二个参数可以是一个算术表达式,可以使用is/2
进行计算。查询?-X=:=2+2
,您将得到一个实例化错误,因为=:=/2
无法将自由变量与数学表达式进行比较<另一方面,code>是/2
,它将左侧的变量与右侧表达式的值统一起来:?-X是2+2。X=4
您使用=:=/2
是可行的(前提是您理顺了变量atom),但您的规则描述了一个低效且迂回的解决方案,原因如下:因为numericValue(Num3,C)
在计算算术之前,Prolog将首先统一numericValue(Num3,C)
与第一个拟合事实,即<代码>数值值(一,1)然后测试1=:=A+B
。当此操作失败时,Prolog将与下一个事实数值值(2,2)
统一,然后测试2=:=A+B
,然后下一个。。。直到它最终发生在正确的值上。与我建议的规则相比:数值A_Num
和B_Num
与C_Num是A_Num+B_Num
相加,将C_Num
与和统一。然后,Prolog将text\u与\u编号(C\u text,C\u Num)
统一为具有C\u Num
适当值的单个拟合事实
定义运算符: 当术语出现在正在定义的
:-
的右侧或程序的顶层时。但是,您不能简单地重新定义谓词(可以这样做,但需要一些簿记和特殊声明。参见,dynamic/1
)。此外,您不想重新定义核心术语,如+/2
和=/2
。但是您可以相对轻松地定义自己的谓词。事实上,使用谓词定义发疯是我最喜欢的Prolog闲置工作之一(尽管我已经阅读了在实践中避免使用不必要的运算符的注意事项,因为它会使代码变得晦涩难懂)
在指令中使用op/3
声明运算符。它具有签名op(+优先级,+类型,:名称)
(参见):
在行动中:
?- one ++ two =::= X.
X = three.
一个主要问题是,在Prolog中,变量以大写字母开头,原子(常量)以小写字母开头。你似乎在好几个地方把这个颠倒过来了。另外,
=/2
是内置的统一运算符(它不是表达式的算术等式)。当您输入A+B=C:-add(A,B,C)
时,尝试重新定义=/2
的含义,这是不允许的。尝试添加(A_文本,B_文本,C_文本):-numericValue(A_文本,A_Num),numericValue(B_文本,B_Num),C_Num是A_Num+B_Num,Num(C_文本,C_Num)。仍然为add(一,一,一)提供true。@rbh假设代码中的其他所有内容都正确,我假设变量ONE
与原子zero
相统一,为您提供add(零,零,零)。
您的序言顶层是否没有显示给出真实结果的ONE
的值?如果我错了,请告诉我。我很乐意看一看您当前的代码。@rbh,如果您试图测试错误的声明“一+一=一”是否为真,您需要添加(一,一,一)
@rbh您是否了解关于以大写字母开头的名称与以小写字母开头的名称的说法add(一,一,一)
就像add(X,X,X)
<代码>一是一个变量X
是一个变量。那是因为它们都以大写字母开头。查询add(ONE,ONE,ONE)
询问当添加到自身时会产生什么值(使用变量ONE
)。答案将是ONE=zero
。另外关于定义运算符,如果我按照您指定的方式定义,它是否也适用于“ONE++two++two=:=six”?
:- op(200, xfx, user:(++)).
:- op(300, yfx, user:(=::=)).
A ++ B =::= C :- add(A, B, C).
?- one ++ two =::= X.
X = three.