Given the following tabular, initially, the lower bound of nb1 is { 8, 31, 43, 55} and its upper bound is the set {1, ..., 81}. The variable nb2 has the lower bound {2, 51, 63, 67}, nb3 the lower bound {10, 39, 49, 59, 74}, nb4 the lower bound { 19, 47, 69, 79} and nb5 the lower bound { 23,29,42,53,64} for example. Such as nb1's upper bound, the upper bound of nb2,..., nb5 is {1, ..., 81}.
| A Sudoku Puzzle | ||||||||
| 2 | 6 | 8 | 1 | |||||
| 3 | 7 | 8 | 6 | |||||
| 4 | 5 | 7 | ||||||
| 5 | 1 | 7 | 9 | |||||
| 3 | 9 | 5 | 1 | |||||
| 4 | 3 | 2 | 5 | |||||
| 1 | 3 | 2 | ||||||
| 5 | 2 | 4 | 9 | |||||
| 3 | 8 | 4 | 6 | |||||
val inputlist2 = [(1,[8,31,43,55]),(2,[2,51,63,67]),
                  (3,[10,39,49,59,74]),(4,[19,47,69,79]),
                  (5,[23,29,42,53,64]),(6,[3,18,80]),
                  (7,[13,27,33]),(8,[7,15,75]),
                  (9,[35,40,72])]
fun sudoku2 inputlist space = 
  let
     val numbers = Vector.tabulate(9,fn x => 
                        FS.upperBound(space,#[(1,81)]))
     val rows = List.tabulate(9,fn x =>(x*9+9-8,x*9+9)) 
     val columns = List.tabulate(9,fn y => 
                       Vector.tabulate(9,fn x =>(x*9+1+y,x*9+1+y)))
     val boxes1 = List.tabulate(3,fn y => 
                   Vector.tabulate(3,fn x =>(x*9+1+y*3,x*9+3+y*3)))
     val boxes2 = List.tabulate(3,fn y => 
                   Vector.tabulate(3,fn x =>(x*9+28+y*3,x*9+30+y*3)))
     val boxes3 = List.tabulate(3,fn y => 
                   Vector.tabulate(3,fn x =>(x*9+55+y*3,x*9+57+y*3)))
     val boxes = List.concat([boxes1,boxes2,boxes3])
     fun constr l = 
       List.app(fn y => 
                 let
                    val tmp1 = FS.Value.make(space,y)
                 in
                    Vector.app(fn x => 
                     let 
                        val tmp2 = FS.setvar space 
                     in
                        FS.relOp(space,x,FS.INTER,tmp1,FS.SEQ,tmp2);
                        FS.cardRange(space,1,1,tmp2)
                     end)numbers
                 end)l
     fun fsDisjoint ([]) = ()
       | fsDisjoint (x::xs) = 
            (List.app(fn y => FS.rel(space,y, FS.DISJ,x))xs;
             fsDisjoint(xs))
  in
    (* use next constraint only, if inputlist is used *)
     List.app(fn(x,y) => 
       List.app(fn z => 
                  let 
                     val tmp = FS.Value.make(space,#[(z,z)])
                  in
                     FS.rel(space,Vector.sub(numbers,x-1),FS.SUP,tmp)
                  end)y)inputlist;
     Vector.app(fn x => FS.cardRange(space,9,9,x))numbers;
    (* the domains of all numbers are pairwise distinct *)
     fsDisjoint(Vector.toList numbers);
    (* distinct numbers in rows *)
     List.app(fn(y,z)=>
       let 
          val tmp1 = FS.Value.make(space,#[(y,z)]) 
       in
          Vector.app(fn x => 
                      let 
                         val tmp2 = FS.setvar space 
                      in
                         FS.relOp(space,x,FS.INTER,tmp1,FS.SEQ,tmp2);
                         FS.cardRange(space,1,1,tmp2)
                      end)numbers
       end)rows;
    (* distinct numbers in columns *)
     constr domainvecs;  
    (* distinct numbers in 3 x 3 boxes *)
     constr boxes;   
     FS.setvarbranch(space,numbers,FS.FSB_MIN_CARD,FS.FSB_MIN); 
     numbers
  end
Andreas Rossberg 2006-08-28