Prolog evaluator that uses previously solved information as input

半腔热情 提交于 2019-12-11 15:57:24

问题


I have written a program that takes a parse tree as input and evaluates it. It works when the identifiers in the tree do not reoccur. I want the evaluator to take in multiple statements, and use the values assigned to identfiers when I solve later statements. Here is my program.

add_op --> ['+'].
assign_op --> ['='].
ident(ident(Ident)) --> [Ident], {atom(Ident)}. /* True if an identifier */
int(int(Int)) --> [Int], {integer(Int)}. /* True if an integer */
semicolon --> [';'].

evaluator(statements(Assignment),VariablesOut):-
    evaluator(Assignment,VariablesOut).

evaluator(statements(Assignment,Statements),VariablesOut):-
    evaluator(Assignment,List1),
    evaluator(Statements,List2),
    merge(List1,List2,VariablesOut).

evaluator(assignment(ident(Ident),assign_op,int(Int),add_op,int(Int2),semicolon),Answer5):-
    Answer2 is Int + Int2,
    atom_concat(Ident,' = ',Answer1),
    atom_concat(Answer1,Answer2,Answer3),
    read_term_from_atom(Answer3, (Answer4), []),    /*removes quotation marks*/
    Answer5 = [Answer4].

The following execution uses a parse tree for a = 2 + 3 ; b = 3 + 4 ; This execution works because my program is only evaluating the answers to a and b, and the evaluation of b does not contain a.

evaluator(statements(assignment(ident(a), assign_op, int(2), add_op, int(3), semicolon), statements(assignment(ident(b), assign_op, int(3), add_op, int(4), semicolon))), Answer).
Answer = [a=5, b=7].

The following uses a parse tree for a = 2 + 3 ; b = a + 4 ;
This one does not work, because b must be the result of 4 added to a, and a is not assigned to the value 5 within the program.

evaluator(statements(assignment(ident(a), assign_op, int(2), add_op, int(3), semicolon), statements(assignment(ident(b), assign_op, int(a), add_op, int(4), semicolon))), Answer).

ERROR: Arithmetic: `a/0' is not a function
ERROR: In:
ERROR:   [11] _2952 is a+4
...

Update

I found a similar solution, but I'm not sure exactly how it works. I don't know where any evaluation is happening and I don't see how the maplist and WithSym =.. lines are needed.

exp_symbols(Symbols, Expr, WithSym) :-
    Expr =.. [F|Args],   /*F is sent to the first element of Expr which in my case would be a = 5 */
    ( member(F=V, Symbols) -> G = V ; G = F ), /* if F followed by a colon and some element V is in the equation, set G to be assign to both V and F */
    maplist(exp_symbols(Symbols), Args, ArgsSWithSym), /*perform the current function on all elements left **/
    WithSym =.. [G|ArgsSWithSym]. /** Set WithSym to be the first element in ArgsSWithSym /**

evaluate(Exp, LstVars, Val) :-
    exp_symbols(LstVars, Exp, NewExp),
    Val is NewExp.

来源:https://stackoverflow.com/questions/48143072/prolog-evaluator-that-uses-previously-solved-information-as-input

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!