SWI-Prolog.Проверьте правильность математического выражения - PullRequest
1 голос
/ 03 апреля 2012

Я пытаюсь проверить правильность математического выражения студента, используя Пролог (SWI-Prolog). Так, например, если ученика попросили добавить три переменные x, y и z, и есть правило, что первые две переменные, которые должны быть добавлены: x и y (в любом порядке), и последняя переменная, которая должна добавьте z, тогда я ожидаю, что пролог может дать мне истинное значение, если ответ студента на любой из них:

х + у + г

(x + y) + 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 Ответ

1 голос
/ 03 апреля 2012

Вы должны попытаться указать грамматику и написать синтаксический анализатор для ваших выражений.

Избегайте утверждать / убирать, что делает программу значительной труднее понять, и вместо этого попытайтесь освоить декларативную модель Пролога .

Выражения рекурсивные структуры данных, использующие операторы с известными приоритетами и ассоциативностью для составления и круглыми скобками для изменения указанного приоритета, где это необходимо.

См. этот ответ для синтаксического анализатора и оценщик, который принимает ввод от 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 .

edit : мы можемпредоставьте шаблон того, что мы хотим, и пусть 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.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...