1
我尝试使用Prolog(SWI-Prolog)检查学生数学表达式的正确性。因此,例如,如果要求学生添加三个变量x,y和z,并且有一条规则,即必须添加的前两个变量是:x和y(以任意顺序),并且必须添加最后一个变量被添加为z然后我想到的是序言可以给我真正的价值,如果学生的答案是任何一种:SWI-Prolog。检查数学表达式的正确性
X + Y + Z
(X + Y)+ Z
Z +(X + Y)
Z + X + Y
Y + X + Z
和许多其他的可能性。
我用下面的规则此检查:
addData :-
assert(variable(v1)),
assert(variable(v2)),
assert(variable(v3)),
assert(varName(v1,x)),
assert(varName(v2,y)),
assert(varName(v3,z)),
assert(varExpr(v1,x)),
assert(varExpr(v2,y)),
assert(varExpr(v3,z)).
add(A,B,R) :- R = A + B.
removeAll :- retractall(variable(X)),
retractall(varName(X,_)),
retractall(varExpr(X,_)).
checkExpr :-
% The first two variable must be x and y, in any combination
( (varExpr(v1,AExpr), varExpr(v2,BExpr));
(varExpr(v2,AExpr), varExpr(v1,BExpr))
),
add(AExpr, BExpr, R1),
% store the expression result as another variable, say v4
retractall(variable(v4)),
retractall(varName(v4, _)),
retractall(varExpr(v4, _)),
assert(variable(v4)),
assert(varName(v4, result)),
assert(varExpr(v4, R1)),
% add the result from prev addition with Z (in any combination)
( (varExpr(v3,CExpr), varExpr(v4,DExpr));
(varExpr(v4,CExpr), varExpr(v3,DExpr))
),
add(CExpr, DExpr, R2),
R2 = z + x + y. % will give me false
% R2 = z + (x + y). % will give me true
% Expected: both should give me true
checkCorrect :- removeAll,
addData,
checkExpr.
您好,谢谢您的建议。但是,在这种情况下,我想有一个代码来解决特定的任务。所以在这种情况下,可以添加的前两个变量是x和y,然后可以将这个添加的结果添加到z中。所以在这种情况下正确的表达式就是:x + y + z,y + x + z,(x + y)+ z,(y + x)+ z,z +(x + y),z +(y + x )。举一个真实的例子来解决这个任务:从摄氏度计算华氏度(d中的商店32)。那么该解决方案只能有:f = c * 1.8 + d,f = 1.8 * c + d,f = d + c * 1.8,f = d + 1.8 * c,以及一些带括号的变体,例如:f = (C * 1.8)+ d。谢谢 – 2012-04-06 02:20:02
好吧,保持* declarative *方法很重要:试图编写* minimal *代码,让您确定正确性。在你的情况下,可以提供*例子*。查看编辑。 – CapelliC 2012-04-06 06:02:46
嗨chac。谢谢。是的,我会尝试在我的程序中做更多的声明性方法。作为一名c#程序员,我以前的方法似乎仍然从我的背景中受到很大影响。例如,我喜欢解决的一个案例(其中会有很多),例如检查学生的数学表达式,将摄氏温度转换为华氏温度。学生可以写出我在前面评论中写出的任何表达方式,但不是任何这些表达式:f = d * 1.8 + c,f = d *(1.8 + c),f = c *(1.8 + d ), 等等。谢谢 – 2012-04-06 06:12:52