The predicates bb_inf/[3,5] implement a simple Branch and
Bound search algorithm for Mixed Integer Linear (MIP) Optimization
examples. Serious MIP is not trivial. The implementation
library('clpqr/bb.pl') is to be understood as a starting point
for more ambitious users who need control over branching, or who want to
add cutting planes, for example.
   
Anyway, here is a small problem from miplib, a collection of MIP models, housed at Rice University:
     NAME:         flugpl
     ROWS:         18
     COLUMNS:      18
     INTEGER:      11
     NONZERO:      46
     BEST SOLN:    1201500 (opt)
     LP SOLN:      1167185.73
     SOURCE:       Harvey M. Wagner
                   John W. Gregory (Cray Research)
                   E. Andrew Boyd (Rice University)
     APPLICATION:  airline model
     COMMENTS:     no integer variables are binary
   
            % library('clpqr/examples/mip')
     
     example(flugpl, Obj, Vs, Ints, []) :-
       Vs = [ Anm1,Anm2,Anm3,Anm4,Anm5,Anm6,
              Stm1,Stm2,Stm3,Stm4,Stm5,Stm6,
              UE1,UE2,UE3,UE4,UE5,UE6],
       Ints = [Stm6, Stm5, Stm4, Stm3, Stm2,
               Anm6, Anm5, Anm4, Anm3, Anm2, Anm1],
     
       Obj =    2700*Stm1 + 1500*Anm1 + 30*UE1
              + 2700*Stm2 + 1500*Anm2 + 30*UE2
              + 2700*Stm3 + 1500*Anm3 + 30*UE3
              + 2700*Stm4 + 1500*Anm4 + 30*UE4
              + 2700*Stm5 + 1500*Anm5 + 30*UE5
              + 2700*Stm6 + 1500*Anm6 + 30*UE6,
     
       allpos(Vs),
       {  Stm1 = 60, 0.9*Stm1 +1*Anm1 -1*Stm2 = 0,
          0.9*Stm2 +1*Anm2 -1*Stm3 = 0, 0.9*Stm3 +1*Anm3 -1*Stm4 = 0,
          0.9*Stm4 +1*Anm4 -1*Stm5 = 0, 0.9*Stm5 +1*Anm5 -1*Stm6 = 0,
          150*Stm1 -100*Anm1 +1*UE1 >= 8000,
          150*Stm2 -100*Anm2 +1*UE2 >= 9000,
          150*Stm3 -100*Anm3 +1*UE3 >= 8000,
          150*Stm4 -100*Anm4 +1*UE4 >= 10000,
          150*Stm5 -100*Anm5 +1*UE5 >= 9000,
          150*Stm6 -100*Anm6 +1*UE6 >= 12000,
          -20*Stm1 +1*UE1 =< 0, -20*Stm2 +1*UE2 =< 0, -20*Stm3 +1*UE3 =< 0,
          -20*Stm4 +1*UE4 =< 0, -20*Stm5 +1*UE5 =< 0, -20*Stm6 +1*UE6 =< 0,
          Anm1 =< 18, 57 =< Stm2, Stm2 =< 75, Anm2 =< 18,
          57 =< Stm3, Stm3 =< 75, Anm3 =< 18, 57 =< Stm4,
          Stm4 =< 75, Anm4 =< 18, 57 =< Stm5, Stm5 =< 75,
          Anm5 =< 18, 57 =< Stm6, Stm6 =< 75, Anm6 =< 18
        }.
     
       allpos([]).
       allpos([X|Xs]) :- {X >= 0}, allpos(Xs).
   We can first check whether the relaxed problem has indeed the quoted infimum:
     clp(r) ?- example(flugpl, Obj, _, _, _), inf(Obj, Inf).
     
     Inf = 1167185.7255923203
   Computing the infimum under the additional constraints that Stm6,
Stm5, Stm4, Stm3, Stm2, Anm6,
Anm5, Anm4, Anm3, Anm2, Anm1 assume
integer values at the infimum is computationally harder, but the
query does not change much:
     clp(r) ?- example(flugpl, Obj, _, Ints, _),
               bb_inf(Ints, Obj, Inf, Vertex, 0.001).
     
     Inf = 1201500.0000000005,
     Vertex = [75.0,70.0,70.0,60.0,60.0,0.0,12.0,7.0,16.0,6.0,6.0]