SWI-Prolog的。检查数学表达式的正确性

时间:2012-04-03 02:15:33

标签: prolog

我尝试使用Prolog(SWI-Prolog)检查学生数学表达的正确性。因此,例如,如果要求学生添加三个变量x,y和z,并且有一个规则,即必须添加的前两个变量是:x和y(以任何顺序),以及必须的最后一个变量如果学生的答案是以下任何一个,我希望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.

1 个答案:

答案 0 :(得分:1)

您应该尝试指定语法并为表达式编写解析器

避免断言/撤回,这会使程序更多更难理解,而是尝试掌握Prolog的声明性模型。

表达式是递归数据结构,使用具有已知优先级关联性运算符进行组合,并使用括号在需要的地方更改指定的优先级。

请参阅this答案,了解解析器评估者,它接受来自 text 的输入。在您的问题中,您将显示代码中的表达式。然后你使用Prolog的解析器来完成脏工作,并且可以简单地在结果语法树上表达你的要求

expression(A + B) :-
  expression(A),
  expression(B).
expression(A * B) :-
  expression(A),
  expression(B).

expression(V) :-
  memberchk(V, [x,y,z]).

?- expression(x+y+(x+z*y)).
true .

编辑:我们可以提供我们想要的模板,让Prolog通过统一来制定详细信息:

% enumerate acceptable expressions
checkExpr(E) :-
  member(E, [F = A + D, F = D + A]),
  F = f,
  A = c * N,
  N = 1.8,
  D = d.

等等......

测试:

?- checkExpr(f=(c*1.8)+d).
true.

?- checkExpr(f=(c*1.8)+e).
false.

?- checkExpr(f=d+c*1.8).
true.