Search code examples
prolog

Formatting the output with proper paranthesis - Prolog (without using ! and --> )


I have the same question as the formatting the output with proper paranthesis - Prolog but the solution should not use ! and -->. The accepted answers from the link has both of these operators. Especially I am looking for a solution using Prolog pattern matching on a rule's parameters.

For convenience sake I am rewriting the question here.

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.

I understand that I am not able modify the output because of =.. predicate.

arithmetic_operator(plus, +).
arithmetic_operator(minus, -).
arithmetic_operator(times, *).

arithmetic_expression(N, N) :- integer(N).

arithmetic_expression(Term, Expr) :-
    Term =.. [Functor,Component1,Component2],
    arithmetic_operator(Functor, Operator),
    arithmetic_expression(Component1, Expr1),
    arithmetic_expression(Component2, Expr2),
    Expr =.. [Operator, Expr1, Expr2].

printterm(Term) :- arithmetic_expression(Term, Expr), format("(~w\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 .


Solution

  • I don't think focusing on I/O like this is the right way to go. The linked answer builds the parenthesized expression as a data structure, which can use nice features like DCGs (the --> rules).

    That said, if you must, you can print fully parenthesized expressions in Prolog like in any other programming language: Using recursion.

    print_term(Term) :-
        arithmetic_expression(Term, Expr),
        print_expr(Expr),
        nl.
    
    print_expr(N) :-
        integer(N),
        write(N).
    print_expr(Expr) :-
        Expr =.. [Operator, Left, Right],
        write('('),
        print_expr(Left),
        write(Operator),
        print_expr(Right),
        write(')').
    
    ?- print_term(plus((minus(8,2)),(times(4,3)))).
    ((8-2)+(4*3))
    true ;
    false.