使用适当的括号格式化输出-Prolog

问题描述

该问题与first order logic creating terms for arithmetic expressions using prolog直接相关。按照链接实现逻辑后,我对printauth/1的Ourput格式存在疑问。当前结果为8-2+4* -3,如何获得类似((8-2)+(4* -3))的东西(请注意,它与+(-(8,2),*(4,-3)))不同。

我一直在尝试在format/2谓词中使用各种选项(\ k,\ q),但没有任何效果。即使我尝试了write_canonical和其他写谓词,仍然没有成功。

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

当前输出

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

预期输出


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

有可能实现这一目标吗?

解决方法

您传递给printterm的术语:

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

通常写为:

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

读该术语时,不需要括号并且确实将其丢失。试试:

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

要获得想要的东西,您似乎真的需要对其进行编程。例如:

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'+,B).
expr_op(minus(A,0'-,B).
expr_op(times(A,0'*,B).

pexp(E) -->
    atomic_expr(E),!.
pexp(E) -->
    { expr_op(E,"(",pexp(B),")".

我得到:

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

为什么不滚动自己的打印谓词?

使它返回一个String,以增加灵活性(因此您可以自由决定是立即将String抽出到现实世界中,还是先对其进行进一步的处理)。

对于所有操作来说都是这样的

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

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

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

然后使用它,请从printterm/1调用它

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