3
votes

I often used SWI-Prolog's feature of being able to do listing(predicate). to see how it implements some of its predicates. I want to see exactly what it does with succ/2 because I'm using it on SWI-Prolog but I need it running with Sicstus too which doesn't have it! I've seen what it does in the SWI manual, tried to implement it but I think it must do something extra to what I've tried. My problem is that the listing feature just gives

% Foreign: succ/2

Any ideas guys?

Thanks :).

2
The predicate is builtin and written in C. Take a look here: swi-prolog.org/git/pl.git?a=history;f=src/pl-arith.c;hb=HEAD - horsh

2 Answers

1
votes

The SWI version is probably implemented in C for better performance. Not being written in Prolog makes it foreign and probably considered a built-in.

Here's my stab at defining SWI's succ/2 in Prolog:

%%%% succ/2 to mimic the SWI Prolog built-in

succ(N0, N1) :-
    ( properly_grounded(N0) 
        ->  N1 is N0 + 1
        ; properly_grounded(N1)
        ->  N1 > 0, N0 is N1 - 1
        ; otherwise 
        -> Ctx=context(succ/2,''),
          throw(error(instantiation_error,Ctx))
       ).

properly_grounded(X):-
    (var(X) -> false
        ; 
    ( X >= 0
        -> true
        ; otherwise 
    -> Ctx = context(succ/2,X),
        E=domain_error(not_less_than_zero,X),
       throw(error(E,Ctx));otherwise
       )
   ).

If necessary, replace otherwise with true and false with fail. The code was developed in SWI, the context part of the exceptions may have to be adjusted for SICStus.

0
votes

This question is super old, but here is a simple implementation that should have the same behavior as succ/2 in SWI-Prolog.

succ(X, Y) :- integer(X), Y is X + 1, X >= 0, !.
succ(X, Y) :- integer(Y), X is Y - 1, X >= 0.

We need both rules, because the right-hand side of is must be fully instantiated, and we check that with integer/1.