5

How to define a as a integer/float number ?

I want to find the results of a+b+c+d=10 where a,b,c,d is integer and >=0.

false
  • 10,264
  • 13
  • 101
  • 209
user198729
  • 61,774
  • 108
  • 250
  • 348

3 Answers3

5

with SWI-Prolog you can use CLP(FD) library

1 ?- use_module(library(clpfd)).
%  library(error) compiled into error 0.00 sec, 9,764 bytes
% library(clpfd) compiled into clpfd 0.05 sec, 227,496 bytes
true.

2 ?- Vars=[A,B,C,D],Vars ins 0..10,sum(Vars,#=,10),label(Vars).
Vars = [0, 0, 0, 10],
A = 0,
B = 0,
C = 0,
D = 10 ;
Vars = [0, 0, 1, 9],
A = 0,
B = 0,
C = 1,
D = 9 ;
Vars = [0, 0, 2, 8],
A = 0,
B = 0,
C = 2,
D = 8 ;
Vars = [0, 0, 3, 7],
A = 0,
B = 0,
C = 3,
D = 7 ;
...
Volodymyr Gubarkov
  • 2,173
  • 20
  • 20
  • Well, first you define 4 variables, then defining domains for variables (from 0..10) then adding constraints (sum of all vars = 10), last statement (label(Vars)) causes search (by backtracking) for all possible variables values. – Volodymyr Gubarkov Dec 24 '09 at 17:14
  • Are ins ,#= keywords of clp?I never see them in prolog before. – user198729 Dec 25 '09 at 03:10
5

Here is a simple, modern, pure Prolog, non-CLP-library solution:

range(X):-
        member(X,[0,1,2,3,4,5,6,7,8,9,10]).

ten(A,B,C,D):-
        range(A),
        range(B),
        range(C),
        range(D),
        10 =:= A + B + C + D.
ThomasH
  • 22,276
  • 13
  • 61
  • 62
  • Is there a more simple way to represent 0~10?I'm worried when the problem's domain is 0~100... – user198729 Dec 26 '09 at 12:43
  • SWI Prolog has the ``between/3`` predicate. ``between(0,100,X)`` will successively bind X to 0..100 inclusively. – ThomasH Dec 26 '09 at 16:32
  • `between/3` for **gnu-prolog** can be found in [GNU Prolog compatibility layer](http://www.david-reitter.com/compling/prolog/compat_gnu.pl) , btw. related stackoverflow question : [Prolog Compatibility Layers - available programming libraries](http://stackoverflow.com/questions/7151675/prolog-compatibility-layers-available-programming-libraries) – Grzegorz Wierzowiecki Aug 22 '11 at 18:44
  • This answer inspired me to [one more related question, here is interlink :).](http://stackoverflow.com/questions/7175258/prolog-generating-list-of-numbers-fitting-given-range) – Grzegorz Wierzowiecki Aug 24 '11 at 12:19
2

Here is GNU-Prolog piece of code with constraint solving over finite domains :

$ gprolog
| ?- [user].
compiling user for byte code...
ten(A,B,C,D) :- fd_domain([A,B,C,D],0,9999999), 10 #= A + B + C + D.

Ctrl + D

| ?- ten(A,B,C,D), fd_labeling([A,B,C,D]).

As you can see, it solves problem of big ranges like 0-9999999

A = 0
B = 0
C = 0
D = 10 ? ;

A = 0
B = 0
C = 1
D = 9 ? ;

A = 0
B = 0
C = 2
D = 8 ? ;
...

P.S. Thanks for Przemysław Kobylański for his blog with clear, very nice Prolog examples, where I've found inspiring examples.

P.P.S. When playing with finite domains, you might like to use fd_set_vector_max/1 . In above case it's not needed, but depending on constraint might be usefull - more details when Gnu-Prolog operates on ranges, when on vectors of possible values, can be found at manual "Finite domain solver and built-in predicates - Introduction"

Grzegorz Wierzowiecki
  • 10,545
  • 9
  • 50
  • 88