First, let's use the Specific Phrase ( dcg ) grammar to bind trees to lists:
inorder (nil) -> [].
inorder (t (Root, L, R)) ->
inorder (L),
[Root],
inorder (R).
The trick I just applied is described in Ulrich Neumerkel's dissertation in the section "Taming the Left Recursion".
"... we add another state for the number of tokens that can be used by newly encountered non-terminals. Therefore, the number of tokens that will be considered by terminals within the same rule is reserved in advance.
In our case:
inorder (nil, Es , Es ) -> [].
inorder (t (Root, L, R), [_ | Es0] , Es ) ->
inorder (L, Es0 , Es1 ),
[Root],
inorder (R, Es1 , Es ).
Request example ( Ls omitted):
? - Ls = [1,2,3], phrase (inorder (Tree, Ls, _), Ls).
Tree = t (1, nil, t (2, nil, t (3, nil, nil)));
Tree = t (1, nil, t (3, t (2, nil, nil), nil));
Tree = t (2, t (1, nil, nil), t (3, nil, nil));
Tree = t (3, t (1, nil, t (2, nil, nil)), nil);
Tree = t (3, t (2, t (1, nil, nil), nil), nil);
false
Another way to solve such problems is to use the tab run mechanism.