:- op(800,xfx,=>).
:- op(800,xfx,==>).
:- op(800,xfx,==>*).

A+(B+C) => (A+B)+C.

A ==> B :-
    A => B.
A+C ==> B+C :-
    A ==> B.
A+B ==> A+C :-
    B ==> C.

A ==>* A.
A ==>* C :-
    A ==> B,
    !,
    B ==>* C.

% ?- a+(b+c+a)+(c+d)+(a+(b+c)) ==>* X.
% und dann wiederholt einen Strichpunkt eingeben!
% Zeigt einen moeglichen Umklammerungsprozess Schritt fuer Schritt.
% Man kann auch den gesamten Umklammerungsprozess ausgeben lassen mit
% ?- a+(b+c+a)+(c+d)+(a+(b+c)) ==>* X, write(X), nl, fail.

% Hier werden auch Terme ausgegeben, die nur teilweise umgeklammert sind.
% Weil die Klausel A ==>* A. vor der Klausel A ==>* C :- ... steht,
% werden Terme in der Reihenfolge von "wenige Umklammerungsschritte"
% hin zu "viele Umklammerungsschritte" ausgegeben.  Der Cut (!) garantiert,
% dass, wenn es fuer einen Term A mehrere Loesungen fuer A ==> B gibt
% (A wird umgeklammert zu B), nur die erste gefundene Loesung verwendet wird.
% Obwohl es also mehrere moegliche Umklammerungsprozesse gibt, wird von
% diesem Programm nur ein Umklammerungsprozess gefunden.
