使用适当的括号格式化输出 - Prolog
formatting the output with proper paranthesis - Prolog
此问题与 直接相关。在按照 link 实施逻辑后,我对 printauth/1
的输入格式有疑问。目前结果为 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,2)),(times(4,3)))).
((8-2)+(4*3))
true .
有可能实现吗?
为什么不推出自己的打印谓词?
将它 return 设为字符串以增加灵活性(这样您就可以自由决定是立即将字符串输出到现实世界,还是先对其进行进一步操作)。
所有操作都是这样的:
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) :- ...
然后要使用它,从 printterm/1
调用它
printterm(Term) :-
arithmetic_expression(Term, Expr),
printterm(Expr,R),
format("~w\n", [R]).
您传递给 printterm
的术语:
plus((minus(8,2)),(times(4,3)))
按照惯例写成:
plus(minus(8, 2), times(4, 3))
括号不是必需的,在阅读术语时确实会丢失。尝试:
?- X = plus((minus(8,2)),(times(4,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'+, 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),
")".
我得到:
?- print_arithmetic_expression(plus(minus(8, 2), times(4, 3))).
(8 - 2) + (4 * 3)
true.
此问题与 printauth/1
的输入格式有疑问。目前结果为 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,2)),(times(4,3)))).
((8-2)+(4*3))
true .
有可能实现吗?
为什么不推出自己的打印谓词?
将它 return 设为字符串以增加灵活性(这样您就可以自由决定是立即将字符串输出到现实世界,还是先对其进行进一步操作)。
所有操作都是这样的:
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) :- ...
然后要使用它,从 printterm/1
printterm(Term) :-
arithmetic_expression(Term, Expr),
printterm(Expr,R),
format("~w\n", [R]).
您传递给 printterm
的术语:
plus((minus(8,2)),(times(4,3)))
按照惯例写成:
plus(minus(8, 2), times(4, 3))
括号不是必需的,在阅读术语时确实会丢失。尝试:
?- X = plus((minus(8,2)),(times(4,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'+, 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),
")".
我得到:
?- print_arithmetic_expression(plus(minus(8, 2), times(4, 3))).
(8 - 2) + (4 * 3)
true.