Search code examples
prologiso-prolog

How to identify valid bodies and convertible terms


is_convertible_term(T) should be true, if T can be converted to a valid body (7.6.2 of ISO/IEC 13211-1). Thus:

?- is_convertible_term((A,B)).
   true.
?- is_convertible_term(A).
   true.
?- is_convertible_term(3.14).
   false.
?- is_convertible_term((a->b;c,!)).
   true.
?- is_convertible_term(\+1).
   true. % because (\+)/1 is a built-in predicate

This should be written in ISO Prolog and it should be as short as possible.

Additionally, is_body(T) should be true, if T is identical to the conversion to a valid body. With the help of it we could for example remove call wrappers (provided there is no interference with !/0 or a top level (->)/2).

?- is_body((a,X)).
   false.
?- is_body((a,call(X))). % this is the conversion of (a,X)
   true.

What I have tried so far, was to start with is_body/1 since it can only be true if is_convertible_term/1 is true. So

is_body(T) :-
   is_convertible_term(T),
   ... .   % <-- here I am stucked

(Just for the sake of completeness, we are considering here ISO Prolog only without any constraint extension, but predicates from the Prolog prologue are fine)


Solution

  • Very short solution.

    is_convertible_term(T) :-
        catch((! ; T), error(type_error(callable,_),_), false).
    
    is_body(T) :-
        \+ \+ (
            term_variables(T, Vs),
            append(Vs, _, [0|Vs]),
            is_convertible_term(T)
        ).