2
votes

I want to write the equivalent psudo-function in prolog:

function underhundred(X){

    if (X >= 0 && X <=100) return 1;
    else return 0;

}

I tried writing this but it does not compile:

underhundred(X,L) :- L is (X => 0, X =< 100 -> L = 1; L = 0) . 

What would be the proper way of writing this without using prolog between predicate?

3

3 Answers

3
votes

If you indeed want to use the goals L=1 and L=0 and X is an integer, use !

:- use_module(library(clpfd)).

Reification works like a charm!

?- X in 0..100 #<==> L.
L in 0..1, X in 0..100#<==>L.

What if X gets instantiated?

?- X in 0..100 #<==> L, X=(-7).
L = 0, X = -7.                    % out of bounds: -7 < 0       =< 100

?- X in 0..100 #<==> L, X=55.
L = 1, X = 55.                    % within bounds:      0 =< 55 =< 100

?- X in 0..100 #<==> L, X=111.   
L = 0, X = 111.                   % out of bounds:      0       =< 100 < 111
0
votes

A Prolog query succeeds or fails. If it succeeds it will return the bindings it made to be true.

You can write this predicate using clpfd as:

:-use_module(library(clpfd)).

under_hundred_clpfd(X):-
X in 0..100.

(You might prefer a name such as between_0_100?, if you literally want under 100 then you can use X in inf..99). Some queries:

?-under_hundred_clpfd(5).
true.

?-under_hundred_clpfd(101).
false.

?-under_hundred_clpfd(X).
X in 0..100.

A traditional way to write this is:

 under_hundred(X):-
 X>=0,
 X=<100.

But this way does not work for uninstantiated variables.

?-under_hundred(X).
ERROR: >/2: Arguments are not sufficiently instantiated

So like you say you might have to put a between/3 or length/2 goal to get a solution or similar construct.

underhundred(X):-
  length(_,X),
  X>=0,
  X=<100.

This is not a very good solution as on back tracking it will get into an infinite loop. between/3 behaves better but you don't want it :).

0
votes

If the main point of the question is how to write an if-then-else construct in Prolog, then a reasonable answer along the lines of the proposed definition is:

underhundred(X,L) :-
   (  X >= 0, X =< 100  )
   -> L = 1
   ;  L = 0.

This will only be useful if underhundred(X,L) is called after X has been sufficiently instantiated.