In lieu of a type system

I’m not suggesting Prolog needs a type system.

But in some cases where I have unruly states to track, I’d like some of the peace of mind one gets with type inference, completeness checks, etc.

It occurred to me that the domain example at Attributed variables gives a foundation of a “poor man’s type checker”.

After some minor changes:

domain(X, Dom) :-
        var(Dom), !,
        get_attr(X, domain, Dom).
domain(X, List) :-
        list_to_set(List, Domain),
        put_attr(Y, domain, Domain),
        X = Y.

% a sort of unified intersection
unisection(List1, List2, Set) :- 
    findall(X, (member(X,List1), member(X,List2)), List3), 
    list_to_set(List3, Set).

attr_unify_hook(Domain, Y) :-
        (   get_attr(Y, domain, Dom2)
        ->  unisection(Domain, Dom2, NewDomain),
            (   NewDomain == []
            ->  fail
            ;   NewDomain = [Value]
            ->  Y = Value
            ;   put_attr(Y, domain, NewDomain)
            )
        ;   var(Y)
        ->  put_attr( Y, domain, Domain )
        ;   member(Y, Domain)
        ).

Then we can have a domain-match-checker.

is_maybe(Y) :- domain(Y, [nothing, just(_)]).

maybe_map(F,MaybeY,D) :- 
    is_maybe(MaybeY), 
    (
        MaybeY = nothing, 
        D = nothing
    ; 
        MaybeY = just(Y), 
        call(F,Y,X), 
        D = just(X)
    ) .


maybe_map(F,MaybeY,D) :- 
    \+ is_maybe(MaybeY), type_error(maybe,MaybeY).

Then use it all:

inc(X,Y) :- #(Y) #= #(X) + 1.

?- domain(X, [M, pizza]), maybe_map(inc, X ,Y).
X = Y, Y = nothing ;
X = just(_A),
Y = just(_B),
clpfd: #=(_A+1, _B) ;

Now I haven’t actually used this yet in my real code. But at first glance it looks like what I think I want for my peace of mind.
Any objections or suggestions?

1 Like

Small, simple – good in that regard. But imho, already elaborate enough that I would probably choose something like the mavis addon instead.

I really love the way mavis is integrated with the comment predicate declarations.