formatting the output with proper paranthesis - Prolog

若如初见. 提交于 2021-02-11 07:58:36

问题


This question is directly related to first order logic creating terms for arithmetic expressions using prolog. After implementing the logic as per the link I have issues with the formatting of the ourput for printauth/1. It currently results as 8-2+4* -3, how is it possible to get something like ((8-2)+(4* -3)) (notice its not the same as +(-(8,2),*(4,-3))).

I have been trying to using various options (\k,\q) in format/2 predicate but nothing works. even I tried write_canonical and other write predicates, still no success.

printterm(Term) :- arithmetic_expression(Term, Expr), format("(~q)\n", [Expr]).
    %write_canonical(Expr).
    %write_term(Expr, [ignore_ops(true)]).
    %format("(~q)\n", [Expr]) .

current output:

?- printterm(plus((minus(8,2)),(times(4,3)))).
(8-2+4*3)
true .

expected output:


?- printterm(plus((minus(8,2)),(times(4,3)))).
((8-2)+(4*3))
true .

Is it possible to achieve this?


回答1:


The term you passed to your printterm:

plus((minus(8,2)),(times(4,3)))

This is conventionally written as:

plus(minus(8, 2), times(4, 3))

The parentheses are not needed and are indeed lost when the term is read. Try:

?- X = plus((minus(8,2)),(times(4,3))).

To get what you want it seems you really need to program it. For example:

print_arithmetic_expression(E) :-
    phrase(parenthesized_expression(E), P),
    format("~s~n", [P]).

parenthesized_expression(E) -->
    atomic_expr(E),
    !.
parenthesized_expression(E) -->
    { expr_op(E, Op, A, B) },
    pexp(A),
    " ", [Op], " ",
    pexp(B).

atomic_expr(E) -->
    { atomic(E),
      format(codes(C), "~w", [E])
    },
    C.

expr_op(plus(A,B), 0'+, A, B).
expr_op(minus(A,B), 0'-, A, B).
expr_op(times(A,B), 0'*, A, B).

pexp(E) -->
    atomic_expr(E),
    !.
pexp(E) -->
    { expr_op(E, Op, A, B) },
    "(",
    pexp(A),
    " ", [Op], " ",
    pexp(B),
    ")".

I get:

?- print_arithmetic_expression(plus(minus(8, 2), times(4, 3))).
(8 - 2) + (4 * 3)
true.



回答2:


Why not roll your own printing predicate?

Make it return a String for added flexibility (so you are free to decide whether to pump the String out to the real world immediately, or manipulate it further first).

Something like this for all operations:

printterm(plus(S1,S2),R) :- 
   printterm(S1,RS1),
   printterm(S2,RS2),
   atomic_list_concat(['(',RS1,'+',RS2,')'],R).

printterm(minus(S1,S2),R) :- ...

printterm(times(S1,S2),R) :- ...

Then to use it, call it from printterm/1

printterm(Term) :- 
   arithmetic_expression(Term, Expr), 
   printterm(Expr,R),
   format("~w\n", [R]).


来源:https://stackoverflow.com/questions/64369051/formatting-the-output-with-proper-paranthesis-prolog

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