src/HOL/Tools/Nitpick/nitpick_kodkod.ML
changeset 34124 c4628a1dcf75
parent 34121 5e831d805118
child 34126 8a2c5d7aff51
equal deleted inserted replaced
34123:c4988215a691 34124:c4628a1dcf75
    17 
    17 
    18   structure NameTable : TABLE
    18   structure NameTable : TABLE
    19 
    19 
    20   val univ_card :
    20   val univ_card :
    21     int -> int -> int -> Kodkod.bound list -> Kodkod.formula -> int
    21     int -> int -> int -> Kodkod.bound list -> Kodkod.formula -> int
       
    22   val check_bits : int -> Kodkod.formula -> unit
    22   val check_arity : int -> int -> unit
    23   val check_arity : int -> int -> unit
    23   val kk_tuple : bool -> int -> int list -> Kodkod.tuple
    24   val kk_tuple : bool -> int -> int list -> Kodkod.tuple
    24   val tuple_set_from_atom_schema : (int * int) list -> Kodkod.tuple_set
    25   val tuple_set_from_atom_schema : (int * int) list -> Kodkod.tuple_set
    25   val sequential_int_bounds : int -> Kodkod.int_bound list
    26   val sequential_int_bounds : int -> Kodkod.int_bound list
       
    27   val pow_of_two_int_bounds : int -> int -> int -> Kodkod.int_bound list
    26   val bounds_for_built_in_rels_in_formula :
    28   val bounds_for_built_in_rels_in_formula :
    27     bool -> int -> int -> int -> int -> Kodkod.formula -> Kodkod.bound list
    29     bool -> int -> int -> int -> int -> Kodkod.formula -> Kodkod.bound list
    28   val bound_for_plain_rel : Proof.context -> bool -> nut -> Kodkod.bound
    30   val bound_for_plain_rel : Proof.context -> bool -> nut -> Kodkod.bound
    29   val bound_for_sel_rel :
    31   val bound_for_sel_rel :
    30     Proof.context -> bool -> dtype_spec list -> nut -> Kodkod.bound
    32     Proof.context -> bool -> dtype_spec list -> nut -> Kodkod.bound
    31   val merge_bounds : Kodkod.bound list -> Kodkod.bound list
    33   val merge_bounds : Kodkod.bound list -> Kodkod.bound list
    32   val declarative_axiom_for_plain_rel : kodkod_constrs -> nut -> Kodkod.formula
    34   val declarative_axiom_for_plain_rel : kodkod_constrs -> nut -> Kodkod.formula
    33   val declarative_axioms_for_datatypes :
    35   val declarative_axioms_for_datatypes :
    34     extended_context -> int Typtab.table -> kodkod_constrs
    36     extended_context -> int -> int Typtab.table -> kodkod_constrs
    35     -> nut NameTable.table -> dtype_spec list -> Kodkod.formula list
    37     -> nut NameTable.table -> dtype_spec list -> Kodkod.formula list
    36   val kodkod_formula_from_nut :
    38   val kodkod_formula_from_nut :
    37     int Typtab.table -> bool -> kodkod_constrs -> nut -> Kodkod.formula
    39     int -> int Typtab.table -> bool -> kodkod_constrs -> nut -> Kodkod.formula
    38 end;
    40 end;
    39 
    41 
    40 structure Nitpick_Kodkod : NITPICK_KODKOD =
    42 structure Nitpick_Kodkod : NITPICK_KODKOD =
    41 struct
    43 struct
    42 
    44 
    78     val tuple_F = {tuple_func = tuple_func, tuple_set_func = tuple_set_func}
    80     val tuple_F = {tuple_func = tuple_func, tuple_set_func = tuple_set_func}
    79     val card = fold (Kodkod.fold_bound expr_F tuple_F) bounds 1
    81     val card = fold (Kodkod.fold_bound expr_F tuple_F) bounds 1
    80                |> Kodkod.fold_formula expr_F formula
    82                |> Kodkod.fold_formula expr_F formula
    81   in Int.max (main_j0 + fold Integer.max [2, nat_card, int_card] 0, card) end
    83   in Int.max (main_j0 + fold Integer.max [2, nat_card, int_card] 0, card) end
    82 
    84 
    83 (* Proof.context -> bool -> string -> typ -> rep -> string *)
    85 (* int -> Kodkod.formula -> unit *)
    84 fun bound_comment ctxt debug nick T R =
    86 fun check_bits bits formula =
    85   short_name nick ^
    87   let
    86   (if debug then " :: " ^ plain_string_from_yxml (Syntax.string_of_typ ctxt T)
    88     (* Kodkod.int_expr -> unit -> unit *)
    87    else "") ^ " : " ^ string_for_rep R
    89     fun int_expr_func (Kodkod.Num k) () =
       
    90         if is_twos_complement_representable bits k then
       
    91           ()
       
    92         else
       
    93           raise TOO_SMALL ("Nitpick_Kodkod.check_bits",
       
    94                            "\"bits\" value " ^ string_of_int bits ^
       
    95                            " too small for problem")
       
    96       | int_expr_func _ () = ()
       
    97     val expr_F = {formula_func = K I, rel_expr_func = K I,
       
    98                   int_expr_func = int_expr_func}
       
    99   in Kodkod.fold_formula expr_F formula () end
    88 
   100 
    89 (* int -> int -> unit *)
   101 (* int -> int -> unit *)
    90 fun check_arity univ_card n =
   102 fun check_arity univ_card n =
    91   if n > Kodkod.max_arity univ_card then
   103   if n > Kodkod.max_arity univ_card then
    92     raise LIMIT ("Nitpick_Kodkod.check_arity",
   104     raise TOO_LARGE ("Nitpick_Kodkod.check_arity",
    93                  "arity " ^ string_of_int n ^ " too large for universe of \
   105                      "arity " ^ string_of_int n ^ " too large for universe of \
    94                  \cardinality " ^ string_of_int univ_card)
   106                      \cardinality " ^ string_of_int univ_card)
    95   else
   107   else
    96     ()
   108     ()
    97 
   109 
    98 (* bool -> int -> int list -> Kodkod.tuple *)
   110 (* bool -> int -> int list -> Kodkod.tuple *)
    99 fun kk_tuple debug univ_card js =
   111 fun kk_tuple debug univ_card js =
   107 val tuple_set_from_atom_schema =
   119 val tuple_set_from_atom_schema =
   108   foldl1 Kodkod.TupleProduct o map Kodkod.TupleAtomSeq
   120   foldl1 Kodkod.TupleProduct o map Kodkod.TupleAtomSeq
   109 (* rep -> Kodkod.tuple_set *)
   121 (* rep -> Kodkod.tuple_set *)
   110 val upper_bound_for_rep = tuple_set_from_atom_schema o atom_schema_of_rep
   122 val upper_bound_for_rep = tuple_set_from_atom_schema o atom_schema_of_rep
   111 
   123 
       
   124 (* int -> Kodkod.tuple_set *)
       
   125 val single_atom = Kodkod.TupleSet o single o Kodkod.Tuple o single
   112 (* int -> Kodkod.int_bound list *)
   126 (* int -> Kodkod.int_bound list *)
   113 fun sequential_int_bounds n =
   127 fun sequential_int_bounds n = [(NONE, map single_atom (index_seq 0 n))]
   114   [(NONE, map (Kodkod.TupleSet o single o Kodkod.Tuple o single)
   128 (* int -> int -> Kodkod.int_bound list *)
   115               (index_seq 0 n))]
   129 fun pow_of_two_int_bounds bits j0 univ_card =
       
   130   let
       
   131     (* int -> int -> int -> Kodkod.int_bound list *)
       
   132     fun aux 0  _ _ = []
       
   133       | aux 1 pow_of_two j =
       
   134         if j < univ_card then [(SOME (~ pow_of_two), [single_atom j])] else []
       
   135       | aux iter pow_of_two j =
       
   136         (SOME pow_of_two, [single_atom j]) ::
       
   137         aux (iter - 1) (2 * pow_of_two) (j + 1)
       
   138   in aux (bits + 1) 1 j0 end
   116 
   139 
   117 (* Kodkod.formula -> Kodkod.n_ary_index list *)
   140 (* Kodkod.formula -> Kodkod.n_ary_index list *)
   118 fun built_in_rels_in_formula formula =
   141 fun built_in_rels_in_formula formula =
   119   let
   142   let
   120     (* Kodkod.rel_expr -> Kodkod.n_ary_index list -> Kodkod.n_ary_index list *)
   143     (* Kodkod.rel_expr -> Kodkod.n_ary_index list -> Kodkod.n_ary_index list *)
   121     fun rel_expr_func (Kodkod.Rel (n, j)) rels =
   144     fun rel_expr_func (r as Kodkod.Rel (x as (n, j))) =
   122         (case AList.lookup (op =) (#rels initial_pool) n of
   145         if x = unsigned_bit_word_sel_rel orelse x = signed_bit_word_sel_rel then
   123            SOME k => (j < k ? insert (op =) (n, j)) rels
   146           I
   124          | NONE => rels)
   147         else
   125       | rel_expr_func _ rels = rels
   148           (case AList.lookup (op =) (#rels initial_pool) n of
       
   149              SOME k => j < k ? insert (op =) x
       
   150            | NONE => I)
       
   151       | rel_expr_func _ = I
   126     val expr_F = {formula_func = K I, rel_expr_func = rel_expr_func,
   152     val expr_F = {formula_func = K I, rel_expr_func = rel_expr_func,
   127                   int_expr_func = K I}
   153                   int_expr_func = K I}
   128   in Kodkod.fold_formula expr_F formula [] end
   154   in Kodkod.fold_formula expr_F formula [] end
   129 
   155 
   130 val max_table_size = 65536
   156 val max_table_size = 65536
   131 
   157 
   132 (* int -> unit *)
   158 (* int -> unit *)
   133 fun check_table_size k =
   159 fun check_table_size k =
   134   if k > max_table_size then
   160   if k > max_table_size then
   135     raise LIMIT ("Nitpick_Kodkod.check_table_size",
   161     raise TOO_LARGE ("Nitpick_Kodkod.check_table_size",
   136                  "precomputed table too large (" ^ string_of_int k ^ ")")
   162                      "precomputed table too large (" ^ string_of_int k ^ ")")
   137   else
   163   else
   138     ()
   164     ()
   139 
   165 
   140 (* bool -> int -> int * int -> (int -> int) -> Kodkod.tuple list *)
   166 (* bool -> int -> int * int -> (int -> int) -> Kodkod.tuple list *)
   141 fun tabulate_func1 debug univ_card (k, j0) f =
   167 fun tabulate_func1 debug univ_card (k, j0) f =
   203 
   229 
   204 (* bool -> int -> int -> int -> int -> int * int
   230 (* bool -> int -> int -> int -> int -> int * int
   205    -> string * bool * Kodkod.tuple list *)
   231    -> string * bool * Kodkod.tuple list *)
   206 fun tabulate_built_in_rel debug univ_card nat_card int_card j0 (x as (n, _)) =
   232 fun tabulate_built_in_rel debug univ_card nat_card int_card j0 (x as (n, _)) =
   207   (check_arity univ_card n;
   233   (check_arity univ_card n;
   208    if Kodkod.Rel x = not3_rel then
   234    if x = not3_rel then
   209      ("not3", tabulate_func1 debug univ_card (2, j0) (curry (op -) 1))
   235      ("not3", tabulate_func1 debug univ_card (2, j0) (curry (op -) 1))
   210    else if Kodkod.Rel x = suc_rel then
   236    else if x = suc_rel then
   211      ("suc", tabulate_func1 debug univ_card (univ_card - j0 - 1, j0)
   237      ("suc", tabulate_func1 debug univ_card (univ_card - j0 - 1, j0)
   212                             (Integer.add 1))
   238                             (Integer.add 1))
   213    else if Kodkod.Rel x = nat_add_rel then
   239    else if x = nat_add_rel then
   214      ("nat_add", tabulate_nat_op2 debug univ_card (nat_card, j0) (op +))
   240      ("nat_add", tabulate_nat_op2 debug univ_card (nat_card, j0) (op +))
   215    else if Kodkod.Rel x = int_add_rel then
   241    else if x = int_add_rel then
   216      ("int_add", tabulate_int_op2 debug univ_card (int_card, j0) (op +))
   242      ("int_add", tabulate_int_op2 debug univ_card (int_card, j0) (op +))
   217    else if Kodkod.Rel x = nat_subtract_rel then
   243    else if x = nat_subtract_rel then
   218      ("nat_subtract",
   244      ("nat_subtract",
   219       tabulate_op2 debug univ_card (nat_card, j0) j0 (uncurry nat_minus))
   245       tabulate_op2 debug univ_card (nat_card, j0) j0 (uncurry nat_minus))
   220    else if Kodkod.Rel x = int_subtract_rel then
   246    else if x = int_subtract_rel then
   221      ("int_subtract", tabulate_int_op2 debug univ_card (int_card, j0) (op -))
   247      ("int_subtract", tabulate_int_op2 debug univ_card (int_card, j0) (op -))
   222    else if Kodkod.Rel x = nat_multiply_rel then
   248    else if x = nat_multiply_rel then
   223      ("nat_multiply", tabulate_nat_op2 debug univ_card (nat_card, j0) (op * ))
   249      ("nat_multiply", tabulate_nat_op2 debug univ_card (nat_card, j0) (op * ))
   224    else if Kodkod.Rel x = int_multiply_rel then
   250    else if x = int_multiply_rel then
   225      ("int_multiply", tabulate_int_op2 debug univ_card (int_card, j0) (op * ))
   251      ("int_multiply", tabulate_int_op2 debug univ_card (int_card, j0) (op * ))
   226    else if Kodkod.Rel x = nat_divide_rel then
   252    else if x = nat_divide_rel then
   227      ("nat_divide", tabulate_nat_op2 debug univ_card (nat_card, j0) isa_div)
   253      ("nat_divide", tabulate_nat_op2 debug univ_card (nat_card, j0) isa_div)
   228    else if Kodkod.Rel x = int_divide_rel then
   254    else if x = int_divide_rel then
   229      ("int_divide", tabulate_int_op2 debug univ_card (int_card, j0) isa_div)
   255      ("int_divide", tabulate_int_op2 debug univ_card (int_card, j0) isa_div)
   230    else if Kodkod.Rel x = nat_modulo_rel then
   256    else if x = nat_less_rel then
   231      ("nat_modulo", tabulate_nat_op2 debug univ_card (nat_card, j0) isa_mod)
       
   232    else if Kodkod.Rel x = int_modulo_rel then
       
   233      ("int_modulo", tabulate_int_op2 debug univ_card (int_card, j0) isa_mod)
       
   234    else if Kodkod.Rel x = nat_less_rel then
       
   235      ("nat_less", tabulate_nat_op2 debug univ_card (nat_card, j0)
   257      ("nat_less", tabulate_nat_op2 debug univ_card (nat_card, j0)
   236                                    (int_for_bool o op <))
   258                                    (int_for_bool o op <))
   237    else if Kodkod.Rel x = int_less_rel then
   259    else if x = int_less_rel then
   238      ("int_less", tabulate_int_op2 debug univ_card (int_card, j0)
   260      ("int_less", tabulate_int_op2 debug univ_card (int_card, j0)
   239                                    (int_for_bool o op <))
   261                                    (int_for_bool o op <))
   240    else if Kodkod.Rel x = gcd_rel then
   262    else if x = gcd_rel then
   241      ("gcd", tabulate_nat_op2 debug univ_card (nat_card, j0) isa_gcd)
   263      ("gcd", tabulate_nat_op2 debug univ_card (nat_card, j0) isa_gcd)
   242    else if Kodkod.Rel x = lcm_rel then
   264    else if x = lcm_rel then
   243      ("lcm", tabulate_nat_op2 debug univ_card (nat_card, j0) isa_lcm)
   265      ("lcm", tabulate_nat_op2 debug univ_card (nat_card, j0) isa_lcm)
   244    else if Kodkod.Rel x = norm_frac_rel then
   266    else if x = norm_frac_rel then
   245      ("norm_frac", tabulate_int_op2_2 debug univ_card (int_card, j0)
   267      ("norm_frac", tabulate_int_op2_2 debug univ_card (int_card, j0)
   246                                       isa_norm_frac)
   268                                       isa_norm_frac)
   247    else
   269    else
   248      raise ARG ("Nitpick_Kodkod.tabulate_built_in_rel", "unknown relation"))
   270      raise ARG ("Nitpick_Kodkod.tabulate_built_in_rel", "unknown relation"))
   249 
   271 
   258 (* bool -> int -> int -> int -> int -> Kodkod.formula -> Kodkod.bound list *)
   280 (* bool -> int -> int -> int -> int -> Kodkod.formula -> Kodkod.bound list *)
   259 fun bounds_for_built_in_rels_in_formula debug univ_card nat_card int_card j0 =
   281 fun bounds_for_built_in_rels_in_formula debug univ_card nat_card int_card j0 =
   260   map (bound_for_built_in_rel debug univ_card nat_card int_card j0)
   282   map (bound_for_built_in_rel debug univ_card nat_card int_card j0)
   261   o built_in_rels_in_formula
   283   o built_in_rels_in_formula
   262 
   284 
       
   285 (* Proof.context -> bool -> string -> typ -> rep -> string *)
       
   286 fun bound_comment ctxt debug nick T R =
       
   287   short_name nick ^
       
   288   (if debug then " :: " ^ plain_string_from_yxml (Syntax.string_of_typ ctxt T)
       
   289    else "") ^ " : " ^ string_for_rep R
       
   290 
   263 (* Proof.context -> bool -> nut -> Kodkod.bound *)
   291 (* Proof.context -> bool -> nut -> Kodkod.bound *)
   264 fun bound_for_plain_rel ctxt debug (u as FreeRel (x, T, R, nick)) =
   292 fun bound_for_plain_rel ctxt debug (u as FreeRel (x, T, R, nick)) =
   265     ([(x, bound_comment ctxt debug nick T R)],
   293     ([(x, bound_comment ctxt debug nick T R)],
   266      if nick = @{const_name bisim_iterator_max} then
   294      if nick = @{const_name bisim_iterator_max} then
   267        case R of
   295        case R of
   268          Atom (k, j0) => [Kodkod.TupleSet [Kodkod.Tuple [k - 1 + j0]]]
   296          Atom (k, j0) => [single_atom (k - 1 + j0)]
   269        | _ => raise NUT ("Nitpick_Kodkod.bound_for_plain_rel", [u])
   297        | _ => raise NUT ("Nitpick_Kodkod.bound_for_plain_rel", [u])
   270      else
   298      else
   271        [Kodkod.TupleSet [], upper_bound_for_rep R])
   299        [Kodkod.TupleSet [], upper_bound_for_rep R])
   272   | bound_for_plain_rel _ _ u =
   300   | bound_for_plain_rel _ _ u =
   273     raise NUT ("Nitpick_Kodkod.bound_for_plain_rel", [u])
   301     raise NUT ("Nitpick_Kodkod.bound_for_plain_rel", [u])
   367           in kk_all decls (kk_xone (fold kk_join vars r)) end
   395           in kk_all decls (kk_xone (fold kk_join vars r)) end
   368       end
   396       end
   369     else
   397     else
   370       Kodkod.True
   398       Kodkod.True
   371   end
   399   end
   372 fun kk_n_ary_function kk R (r as Kodkod.Rel _) =
   400 fun kk_n_ary_function kk R (r as Kodkod.Rel x) =
   373     if not (is_opt_rep R) then
   401     if not (is_opt_rep R) then
   374       if r = suc_rel then
   402       if x = suc_rel then
   375         Kodkod.False
   403         Kodkod.False
   376       else if r = nat_add_rel then
   404       else if x = nat_add_rel then
   377         formula_for_bool (card_of_rep (body_rep R) = 1)
   405         formula_for_bool (card_of_rep (body_rep R) = 1)
   378       else if r = nat_multiply_rel then
   406       else if x = nat_multiply_rel then
   379         formula_for_bool (card_of_rep (body_rep R) <= 2)
   407         formula_for_bool (card_of_rep (body_rep R) <= 2)
   380       else
   408       else
   381         d_n_ary_function kk R r
   409         d_n_ary_function kk R r
   382     else if r = nat_subtract_rel then
   410     else if x = nat_subtract_rel then
   383       Kodkod.True
   411       Kodkod.True
   384     else
   412     else
   385       d_n_ary_function kk R r
   413       d_n_ary_function kk R r
   386   | kk_n_ary_function kk R r = d_n_ary_function kk R r
   414   | kk_n_ary_function kk R r = d_n_ary_function kk R r
   387 
   415 
   391                      (r :: rs) =
   419                      (r :: rs) =
   392     fold (kk_and o kk_no o kk_intersect r) rs (kk_disjoint_sets kk rs)
   420     fold (kk_and o kk_no o kk_intersect r) rs (kk_disjoint_sets kk rs)
   393 
   421 
   394 (* int -> kodkod_constrs -> (Kodkod.rel_expr -> Kodkod.rel_expr)
   422 (* int -> kodkod_constrs -> (Kodkod.rel_expr -> Kodkod.rel_expr)
   395    -> Kodkod.rel_expr -> Kodkod.rel_expr *)
   423    -> Kodkod.rel_expr -> Kodkod.rel_expr *)
   396 fun basic_rel_let j ({kk_rel_let, ...} : kodkod_constrs) f r =
   424 fun basic_rel_rel_let j ({kk_rel_let, ...} : kodkod_constrs) f r =
   397   if inline_rel_expr r then
   425   if inline_rel_expr r then
   398     f r
   426     f r
   399   else
   427   else
   400     let val x = (Kodkod.arity_of_rel_expr r, j) in
   428     let val x = (Kodkod.arity_of_rel_expr r, j) in
   401       kk_rel_let [Kodkod.AssignRelReg (x, r)] (f (Kodkod.RelReg x))
   429       kk_rel_let [Kodkod.AssignRelReg (x, r)] (f (Kodkod.RelReg x))
   402     end
   430     end
   403 
       
   404 (* kodkod_constrs -> (Kodkod.rel_expr -> Kodkod.rel_expr) -> Kodkod.rel_expr
   431 (* kodkod_constrs -> (Kodkod.rel_expr -> Kodkod.rel_expr) -> Kodkod.rel_expr
   405    -> Kodkod.rel_expr *)
   432    -> Kodkod.rel_expr *)
   406 val single_rel_let = basic_rel_let 0
   433 val single_rel_rel_let = basic_rel_rel_let 0
   407 (* kodkod_constrs -> (Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr)
   434 (* kodkod_constrs -> (Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr)
   408    -> Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr *)
   435    -> Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr *)
   409 fun double_rel_let kk f r1 r2 =
   436 fun double_rel_rel_let kk f r1 r2 =
   410   single_rel_let kk (fn r1 => basic_rel_let 1 kk (f r1) r2) r1
   437   single_rel_rel_let kk (fn r1 => basic_rel_rel_let 1 kk (f r1) r2) r1
   411 (* kodkod_constrs
   438 (* kodkod_constrs
   412    -> (Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr)
   439    -> (Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr)
   413    -> Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr
   440    -> Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr
   414    -> Kodkod.rel_expr *)
   441    -> Kodkod.rel_expr *)
   415 fun triple_rel_let kk f r1 r2 r3 =
   442 fun tripl_rel_rel_let kk f r1 r2 r3 =
   416   double_rel_let kk (fn r1 => fn r2 => basic_rel_let 2 kk (f r1 r2) r3) r1 r2
   443   double_rel_rel_let kk
       
   444       (fn r1 => fn r2 => basic_rel_rel_let 2 kk (f r1 r2) r3) r1 r2
   417 
   445 
   418 (* kodkod_constrs -> int -> Kodkod.formula -> Kodkod.rel_expr *)
   446 (* kodkod_constrs -> int -> Kodkod.formula -> Kodkod.rel_expr *)
   419 fun atom_from_formula ({kk_rel_if, ...} : kodkod_constrs) j0 f =
   447 fun atom_from_formula ({kk_rel_if, ...} : kodkod_constrs) j0 f =
   420   kk_rel_if f (Kodkod.Atom (j0 + 1)) (Kodkod.Atom j0)
   448   kk_rel_if f (Kodkod.Atom (j0 + 1)) (Kodkod.Atom j0)
   421 (* kodkod_constrs -> rep -> Kodkod.formula -> Kodkod.rel_expr *)
   449 (* kodkod_constrs -> rep -> Kodkod.formula -> Kodkod.rel_expr *)
   467   else
   495   else
   468     let val card = card_of_rep old_R in
   496     let val card = card_of_rep old_R in
   469       if is_lone_rep old_R andalso is_lone_rep new_R
   497       if is_lone_rep old_R andalso is_lone_rep new_R
   470          andalso card = card_of_rep new_R then
   498          andalso card = card_of_rep new_R then
   471         if card >= lone_rep_fallback_max_card then
   499         if card >= lone_rep_fallback_max_card then
   472           raise LIMIT ("Nitpick_Kodkod.lone_rep_fallback",
   500           raise TOO_LARGE ("Nitpick_Kodkod.lone_rep_fallback",
   473                        "too high cardinality (" ^ string_of_int card ^ ")")
   501                            "too high cardinality (" ^ string_of_int card ^ ")")
   474         else
   502         else
   475           kk_case_switch kk old_R new_R r (all_singletons_for_rep old_R)
   503           kk_case_switch kk old_R new_R r (all_singletons_for_rep old_R)
   476                          (all_singletons_for_rep new_R)
   504                          (all_singletons_for_rep new_R)
   477       else
   505       else
   478         raise REP ("Nitpick_Kodkod.lone_rep_fallback", [old_R, new_R])
   506         raise REP ("Nitpick_Kodkod.lone_rep_fallback", [old_R, new_R])
   670           unopt_old_R r
   698           unopt_old_R r
   671   end
   699   end
   672 (* kodkod_constrs -> rep -> rep -> rep -> Kodkod.rel_expr -> Kodkod.rel_expr *)
   700 (* kodkod_constrs -> rep -> rep -> rep -> Kodkod.rel_expr -> Kodkod.rel_expr *)
   673 and rel_expr_to_func kk R1 R2 = rel_expr_from_rel_expr kk (Func (R1, R2))
   701 and rel_expr_to_func kk R1 R2 = rel_expr_from_rel_expr kk (Func (R1, R2))
   674 
   702 
       
   703 (* kodkod_constrs -> typ -> Kodkod.rel_expr -> Kodkod.rel_expr *)
       
   704 fun bit_set_from_atom ({kk_join, ...} : kodkod_constrs) T r =
       
   705   kk_join r (Kodkod.Rel (if T = @{typ "unsigned_bit word"} then
       
   706                            unsigned_bit_word_sel_rel
       
   707                          else
       
   708                            signed_bit_word_sel_rel))
       
   709 (* kodkod_constrs -> typ -> Kodkod.rel_expr -> Kodkod.int_expr *)
       
   710 val int_expr_from_atom = Kodkod.SetSum ooo bit_set_from_atom
       
   711 (* kodkod_constrs -> typ -> rep -> Kodkod.int_expr -> Kodkod.rel_expr *)
       
   712 fun atom_from_int_expr (kk as {kk_rel_eq, kk_comprehension, ...}
       
   713                         : kodkod_constrs) T R i =
       
   714   kk_comprehension (decls_for_atom_schema ~1 (atom_schema_of_rep R))
       
   715                    (kk_rel_eq (bit_set_from_atom kk T (Kodkod.Var (1, ~1)))
       
   716                               (Kodkod.Bits i))
       
   717 
   675 (* kodkod_constrs -> nut -> Kodkod.formula *)
   718 (* kodkod_constrs -> nut -> Kodkod.formula *)
   676 fun declarative_axiom_for_plain_rel kk (FreeRel (x, _, R as Func _, nick)) =
   719 fun declarative_axiom_for_plain_rel kk (FreeRel (x, _, R as Func _, nick)) =
   677     kk_n_ary_function kk (R |> nick = @{const_name List.set} ? unopt_rep)
   720     kk_n_ary_function kk (R |> nick = @{const_name List.set} ? unopt_rep)
   678                       (Kodkod.Rel x)
   721                       (Kodkod.Rel x)
   679   | declarative_axiom_for_plain_rel ({kk_lone, kk_one, ...} : kodkod_constrs)
   722   | declarative_axiom_for_plain_rel ({kk_lone, kk_one, ...} : kodkod_constrs)
   802                (kk_formula_if (kk_subset (Kodkod.Var (1, 0)) dom_r)
   845                (kk_formula_if (kk_subset (Kodkod.Var (1, 0)) dom_r)
   803                               (kk_n_ary_function kk R2 r')
   846                               (kk_n_ary_function kk R2 r')
   804                               (kk_no r'))
   847                               (kk_no r'))
   805       end
   848       end
   806   end
   849   end
   807 (* extended_context -> int -> kodkod_constrs -> nut NameTable.table
   850 (* extended_context -> int -> int -> kodkod_constrs -> nut NameTable.table
   808    -> constr_spec -> Kodkod.formula list *)
   851    -> constr_spec -> Kodkod.formula list *)
   809 fun sel_axioms_for_constr ext_ctxt j0 kk rel_table
   852 fun sel_axioms_for_constr ext_ctxt bits j0 kk rel_table
   810         (constr as {const, delta, epsilon, explicit_max, ...}) =
   853         (constr as {const, delta, epsilon, explicit_max, ...}) =
   811   let
   854   let
   812     val honors_explicit_max =
   855     val honors_explicit_max =
   813       explicit_max < 0 orelse epsilon - delta <= explicit_max
   856       explicit_max < 0 orelse epsilon - delta <= explicit_max
   814   in
   857   in
   816       [formula_for_bool honors_explicit_max]
   859       [formula_for_bool honors_explicit_max]
   817     else
   860     else
   818       let
   861       let
   819         val ran_r = discr_rel_expr rel_table const
   862         val ran_r = discr_rel_expr rel_table const
   820         val max_axiom =
   863         val max_axiom =
   821           if honors_explicit_max then Kodkod.True
   864           if honors_explicit_max then
   822           else Kodkod.LE (Kodkod.Cardinality ran_r, Kodkod.Num explicit_max)
   865             Kodkod.True
       
   866           else if is_twos_complement_representable bits (epsilon - delta) then
       
   867             Kodkod.LE (Kodkod.Cardinality ran_r, Kodkod.Num explicit_max)
       
   868           else
       
   869             raise TOO_SMALL ("Nitpick_Kodkod.sel_axioms_for_constr",
       
   870                              "\"bits\" value " ^ string_of_int bits ^
       
   871                              " too small for \"max\"")
   823       in
   872       in
   824         max_axiom ::
   873         max_axiom ::
   825         map (sel_axiom_for_sel ext_ctxt j0 kk rel_table ran_r constr)
   874         map (sel_axiom_for_sel ext_ctxt j0 kk rel_table ran_r constr)
   826             (index_seq 0 (num_sels_for_constr_type (snd const)))
   875             (index_seq 0 (num_sels_for_constr_type (snd const)))
   827       end
   876       end
   828   end
   877   end
   829 (* extended_context -> int -> kodkod_constrs -> nut NameTable.table
   878 (* extended_context -> int -> int -> kodkod_constrs -> nut NameTable.table
   830    -> dtype_spec -> Kodkod.formula list *)
   879    -> dtype_spec -> Kodkod.formula list *)
   831 fun sel_axioms_for_datatype ext_ctxt j0 kk rel_table
   880 fun sel_axioms_for_datatype ext_ctxt bits j0 kk rel_table
   832                             ({constrs, ...} : dtype_spec) =
   881                             ({constrs, ...} : dtype_spec) =
   833   maps (sel_axioms_for_constr ext_ctxt j0 kk rel_table) constrs
   882   maps (sel_axioms_for_constr ext_ctxt bits j0 kk rel_table) constrs
   834 
   883 
   835 (* extended_context -> kodkod_constrs -> nut NameTable.table -> constr_spec
   884 (* extended_context -> kodkod_constrs -> nut NameTable.table -> constr_spec
   836    -> Kodkod.formula list *)
   885    -> Kodkod.formula list *)
   837 fun uniqueness_axiom_for_constr ext_ctxt
   886 fun uniqueness_axiom_for_constr ext_ctxt
   838         ({kk_all, kk_implies, kk_and, kk_rel_eq, kk_lone, kk_join, ...}
   887         ({kk_all, kk_implies, kk_and, kk_rel_eq, kk_lone, kk_join, ...}
   879     let val rs = map (discr_rel_expr rel_table o #const) constrs in
   928     let val rs = map (discr_rel_expr rel_table o #const) constrs in
   880       [kk_rel_eq (fold1 kk_union rs) (Kodkod.AtomSeq (card, j0)),
   929       [kk_rel_eq (fold1 kk_union rs) (Kodkod.AtomSeq (card, j0)),
   881        kk_disjoint_sets kk rs]
   930        kk_disjoint_sets kk rs]
   882     end
   931     end
   883 
   932 
   884 (* extended_context -> int Typtab.table -> kodkod_constrs -> nut NameTable.table
   933 (* extended_context -> int -> int Typtab.table -> kodkod_constrs
   885    -> dtype_spec -> Kodkod.formula list *)
   934    -> nut NameTable.table -> dtype_spec -> Kodkod.formula list *)
   886 fun other_axioms_for_datatype _ _ _ _ {shallow = true, ...} = []
   935 fun other_axioms_for_datatype _ _ _ _ _ {shallow = true, ...} = []
   887   | other_axioms_for_datatype ext_ctxt ofs kk rel_table (dtype as {typ, ...}) =
   936   | other_axioms_for_datatype ext_ctxt bits ofs kk rel_table
       
   937                               (dtype as {typ, ...}) =
   888     let val j0 = offset_of_type ofs typ in
   938     let val j0 = offset_of_type ofs typ in
   889       sel_axioms_for_datatype ext_ctxt j0 kk rel_table dtype @
   939       sel_axioms_for_datatype ext_ctxt bits j0 kk rel_table dtype @
   890       uniqueness_axioms_for_datatype ext_ctxt kk rel_table dtype @
   940       uniqueness_axioms_for_datatype ext_ctxt kk rel_table dtype @
   891       partition_axioms_for_datatype j0 kk rel_table dtype
   941       partition_axioms_for_datatype j0 kk rel_table dtype
   892     end
   942     end
   893 
   943 
   894 (* extended_context -> int Typtab.table -> kodkod_constrs -> nut NameTable.table
   944 (* extended_context -> int -> int Typtab.table -> kodkod_constrs
   895    -> dtype_spec list -> Kodkod.formula list *)
   945    -> nut NameTable.table -> dtype_spec list -> Kodkod.formula list *)
   896 fun declarative_axioms_for_datatypes ext_ctxt ofs kk rel_table dtypes =
   946 fun declarative_axioms_for_datatypes ext_ctxt bits ofs kk rel_table dtypes =
   897   acyclicity_axioms_for_datatypes ext_ctxt kk rel_table dtypes @
   947   acyclicity_axioms_for_datatypes ext_ctxt kk rel_table dtypes @
   898   maps (other_axioms_for_datatype ext_ctxt ofs kk rel_table) dtypes
   948   maps (other_axioms_for_datatype ext_ctxt bits ofs kk rel_table) dtypes
   899 
   949 
   900 (* int Typtab.table -> bool -> kodkod_constrs -> nut -> Kodkod.formula *)
   950 (* int -> int Typtab.table -> bool -> kodkod_constrs -> nut -> Kodkod.formula *)
   901 fun kodkod_formula_from_nut ofs liberal
   951 fun kodkod_formula_from_nut bits ofs liberal
   902         (kk as {kk_all, kk_exist, kk_formula_let, kk_formula_if, kk_or, kk_not,
   952         (kk as {kk_all, kk_exist, kk_formula_let, kk_formula_if, kk_or, kk_not,
   903                 kk_iff, kk_implies, kk_and, kk_subset, kk_rel_eq, kk_no, kk_one,
   953                 kk_iff, kk_implies, kk_and, kk_subset, kk_rel_eq, kk_no, kk_one,
   904                 kk_some, kk_rel_let, kk_rel_if, kk_union, kk_difference,
   954                 kk_some, kk_rel_let, kk_rel_if, kk_union, kk_difference,
   905                 kk_intersect, kk_product, kk_join, kk_closure, kk_comprehension,
   955                 kk_intersect, kk_product, kk_join, kk_closure, kk_comprehension,
   906                 kk_project, kk_project_seq, kk_not3, kk_nat_less, kk_int_less,
   956                 kk_project, kk_project_seq, kk_not3, kk_nat_less, kk_int_less,
   922 
   972 
   923     (* Kodkod.formula -> Kodkod.formula -> Kodkod.formula *)
   973     (* Kodkod.formula -> Kodkod.formula -> Kodkod.formula *)
   924     fun kk_notimplies f1 f2 = kk_and f1 (kk_not f2)
   974     fun kk_notimplies f1 f2 = kk_and f1 (kk_not f2)
   925     (* Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr *)
   975     (* Kodkod.rel_expr -> Kodkod.rel_expr -> Kodkod.rel_expr *)
   926     val kk_or3 =
   976     val kk_or3 =
   927       double_rel_let kk
   977       double_rel_rel_let kk
   928           (fn r1 => fn r2 =>
   978           (fn r1 => fn r2 =>
   929               kk_rel_if (kk_subset true_atom (kk_union r1 r2)) true_atom
   979               kk_rel_if (kk_subset true_atom (kk_union r1 r2)) true_atom
   930                         (kk_intersect r1 r2))
   980                         (kk_intersect r1 r2))
   931     val kk_and3 =
   981     val kk_and3 =
   932       double_rel_let kk
   982       double_rel_rel_let kk
   933           (fn r1 => fn r2 =>
   983           (fn r1 => fn r2 =>
   934               kk_rel_if (kk_subset false_atom (kk_union r1 r2)) false_atom
   984               kk_rel_if (kk_subset false_atom (kk_union r1 r2)) false_atom
   935                         (kk_intersect r1 r2))
   985                         (kk_intersect r1 r2))
   936     fun kk_notimplies3 r1 r2 = kk_and3 r1 (kk_not3 r2)
   986     fun kk_notimplies3 r1 r2 = kk_and3 r1 (kk_not3 r2)
   937 
   987 
  1151                            (rel_expr_from_rel_expr kk min_R R2 r2))
  1201                            (rel_expr_from_rel_expr kk min_R R2 r2))
  1152           end
  1202           end
  1153       | Cst (Iden, T, Func (Atom (1, j0), Formula Neut)) => Kodkod.Atom j0
  1203       | Cst (Iden, T, Func (Atom (1, j0), Formula Neut)) => Kodkod.Atom j0
  1154       | Cst (Iden, T as Type ("fun", [T1, _]), R as Func (R1, _)) =>
  1204       | Cst (Iden, T as Type ("fun", [T1, _]), R as Func (R1, _)) =>
  1155         to_rep R (Cst (Iden, T, Func (one_rep ofs T1 R1, Formula Neut)))
  1205         to_rep R (Cst (Iden, T, Func (one_rep ofs T1 R1, Formula Neut)))
  1156       | Cst (Num j, @{typ int}, R) =>
  1206       | Cst (Num j, T, R) =>
  1157          (case atom_for_int (card_of_rep R, offset_of_type ofs int_T) j of
  1207         if is_word_type T then
       
  1208           atom_from_int_expr kk T R (Kodkod.Num j)
       
  1209         else if T = int_T then
       
  1210           case atom_for_int (card_of_rep R, offset_of_type ofs int_T) j of
  1158             ~1 => if is_opt_rep R then Kodkod.None
  1211             ~1 => if is_opt_rep R then Kodkod.None
  1159                   else raise NUT ("Nitpick_Kodkod.to_r (Num)", [u])
  1212                   else raise NUT ("Nitpick_Kodkod.to_r (Num)", [u])
  1160           | j' => Kodkod.Atom j')
  1213           | j' => Kodkod.Atom j'
  1161       | Cst (Num j, T, R) =>
  1214         else
  1162         if j < card_of_rep R then Kodkod.Atom (j + offset_of_type ofs T)
  1215           if j < card_of_rep R then Kodkod.Atom (j + offset_of_type ofs T)
  1163         else if is_opt_rep R then Kodkod.None
  1216           else if is_opt_rep R then Kodkod.None
  1164         else raise NUT ("Nitpick_Kodkod.to_r", [u])
  1217           else raise NUT ("Nitpick_Kodkod.to_r (Num)", [u])
  1165       | Cst (Unknown, _, R) => empty_rel_for_rep R
  1218       | Cst (Unknown, _, R) => empty_rel_for_rep R
  1166       | Cst (Unrep, _, R) => empty_rel_for_rep R
  1219       | Cst (Unrep, _, R) => empty_rel_for_rep R
  1167       | Cst (Suc, T, Func (Atom x, _)) =>
  1220       | Cst (Suc, T, Func (Atom x, _)) =>
  1168         if domain_type T <> nat_T then suc_rel
  1221         if domain_type T <> nat_T then
  1169         else kk_intersect suc_rel (kk_product Kodkod.Univ (Kodkod.AtomSeq x))
  1222           Kodkod.Rel suc_rel
  1170       | Cst (Add, Type ("fun", [@{typ nat}, _]), _) => nat_add_rel
  1223         else
  1171       | Cst (Add, Type ("fun", [@{typ int}, _]), _) => int_add_rel
  1224           kk_intersect (Kodkod.Rel suc_rel)
  1172       | Cst (Subtract, Type ("fun", [@{typ nat}, _]), _) => nat_subtract_rel
  1225                        (kk_product Kodkod.Univ (Kodkod.AtomSeq x))
  1173       | Cst (Subtract, Type ("fun", [@{typ int}, _]), _) => int_subtract_rel
  1226       | Cst (Add, Type ("fun", [@{typ nat}, _]), _) => Kodkod.Rel nat_add_rel
  1174       | Cst (Multiply, Type ("fun", [@{typ nat}, _]), _) => nat_multiply_rel
  1227       | Cst (Add, Type ("fun", [@{typ int}, _]), _) => Kodkod.Rel int_add_rel
  1175       | Cst (Multiply, Type ("fun", [@{typ int}, _]), _) => int_multiply_rel
  1228       | Cst (Add, T as Type ("fun", [@{typ "unsigned_bit word"}, _]), R) =>
  1176       | Cst (Divide, Type ("fun", [@{typ nat}, _]), _) => nat_divide_rel
  1229         to_bit_word_binary_op T R NONE (SOME (curry Kodkod.Add))
  1177       | Cst (Divide, Type ("fun", [@{typ int}, _]), _) => int_divide_rel
  1230       | Cst (Add, T as Type ("fun", [@{typ "signed_bit word"}, _]), R) =>
  1178       | Cst (Modulo, Type ("fun", [@{typ nat}, _]), _) => nat_modulo_rel
  1231         to_bit_word_binary_op T R
  1179       | Cst (Modulo, Type ("fun", [@{typ int}, _]), _) => int_modulo_rel
  1232             (SOME (fn i1 => fn i2 => fn i3 =>
  1180       | Cst (Gcd, _, _) => gcd_rel
  1233                  kk_implies (Kodkod.LE (Kodkod.Num 0, Kodkod.BitXor (i1, i2)))
  1181       | Cst (Lcm, _, _) => lcm_rel
  1234                             (Kodkod.LE (Kodkod.Num 0, Kodkod.BitXor (i2, i3)))))
       
  1235             (SOME (curry Kodkod.Add))
       
  1236       | Cst (Subtract, Type ("fun", [@{typ nat}, _]), _) =>
       
  1237         Kodkod.Rel nat_subtract_rel
       
  1238       | Cst (Subtract, Type ("fun", [@{typ int}, _]), _) =>
       
  1239         Kodkod.Rel int_subtract_rel
       
  1240       | Cst (Subtract, T as Type ("fun", [@{typ "unsigned_bit word"}, _]), R) =>
       
  1241         to_bit_word_binary_op T R NONE
       
  1242             (SOME (fn i1 => fn i2 =>
       
  1243                       Kodkod.IntIf (Kodkod.LE (i1, i2), Kodkod.Num 0,
       
  1244                                     Kodkod.Sub (i1, i2))))
       
  1245       | Cst (Subtract, T as Type ("fun", [@{typ "signed_bit word"}, _]), R) =>
       
  1246         to_bit_word_binary_op T R
       
  1247             (SOME (fn i1 => fn i2 => fn i3 =>
       
  1248                  kk_implies (Kodkod.LT (Kodkod.BitXor (i1, i2), Kodkod.Num 0))
       
  1249                             (Kodkod.LT (Kodkod.BitXor (i2, i3), Kodkod.Num 0))))
       
  1250             (SOME (curry Kodkod.Sub))
       
  1251       | Cst (Multiply, Type ("fun", [@{typ nat}, _]), _) =>
       
  1252         Kodkod.Rel nat_multiply_rel
       
  1253       | Cst (Multiply, Type ("fun", [@{typ int}, _]), _) =>
       
  1254         Kodkod.Rel int_multiply_rel
       
  1255       | Cst (Multiply,
       
  1256              T as Type ("fun", [Type (@{type_name word}, [bit_T]), _]), R) =>
       
  1257         to_bit_word_binary_op T R
       
  1258             (SOME (fn i1 => fn i2 => fn i3 =>
       
  1259                 kk_or (Kodkod.IntEq (i2, Kodkod.Num 0))
       
  1260                       (Kodkod.IntEq (Kodkod.Div (i3, i2), i1)
       
  1261                        |> bit_T = @{typ signed_bit}
       
  1262                           ? kk_and (Kodkod.LE (Kodkod.Num 0,
       
  1263                                           foldl1 Kodkod.BitAnd [i1, i2, i3])))))
       
  1264             (SOME (curry Kodkod.Mult))
       
  1265       | Cst (Divide, Type ("fun", [@{typ nat}, _]), _) =>
       
  1266         Kodkod.Rel nat_divide_rel
       
  1267       | Cst (Divide, Type ("fun", [@{typ int}, _]), _) =>
       
  1268         Kodkod.Rel int_divide_rel
       
  1269       | Cst (Divide, T as Type ("fun", [@{typ "unsigned_bit word"}, _]), R) =>
       
  1270         to_bit_word_binary_op T R NONE
       
  1271             (SOME (fn i1 => fn i2 =>
       
  1272                       Kodkod.IntIf (Kodkod.IntEq (i2, Kodkod.Num 0),
       
  1273                                     Kodkod.Num 0, Kodkod.Div (i1, i2))))
       
  1274       | Cst (Divide, T as Type ("fun", [@{typ "signed_bit word"}, _]), R) =>
       
  1275         to_bit_word_binary_op T R
       
  1276             (SOME (fn i1 => fn i2 => fn i3 =>
       
  1277                 Kodkod.LE (Kodkod.Num 0, foldl1 Kodkod.BitAnd [i1, i2, i3])))
       
  1278             (SOME (fn i1 => fn i2 =>
       
  1279                  Kodkod.IntIf (kk_and (Kodkod.LT (i1, Kodkod.Num 0))
       
  1280                                       (Kodkod.LT (Kodkod.Num 0, i2)),
       
  1281                      Kodkod.Sub (Kodkod.Div (Kodkod.Add (i1, Kodkod.Num 1), i2),
       
  1282                                  Kodkod.Num 1),
       
  1283                      Kodkod.IntIf (kk_and (Kodkod.LT (Kodkod.Num 0, i1))
       
  1284                                           (Kodkod.LT (i2, Kodkod.Num 0)),
       
  1285                          Kodkod.Sub (Kodkod.Div (Kodkod.Sub (i1, Kodkod.Num 1),
       
  1286                                                  i2), Kodkod.Num 1),
       
  1287                          Kodkod.IntIf (Kodkod.IntEq (i2, Kodkod.Num 0),
       
  1288                                        Kodkod.Num 0, Kodkod.Div (i1, i2))))))
       
  1289       | Cst (Gcd, _, _) => Kodkod.Rel gcd_rel
       
  1290       | Cst (Lcm, _, _) => Kodkod.Rel lcm_rel
  1182       | Cst (Fracs, _, Func (Atom (1, _), _)) => Kodkod.None
  1291       | Cst (Fracs, _, Func (Atom (1, _), _)) => Kodkod.None
  1183       | Cst (Fracs, _, Func (Struct _, _)) =>
  1292       | Cst (Fracs, _, Func (Struct _, _)) =>
  1184         kk_project_seq norm_frac_rel 2 2
  1293         kk_project_seq (Kodkod.Rel norm_frac_rel) 2 2
  1185       | Cst (NormFrac, _, _) => norm_frac_rel
  1294       | Cst (NormFrac, _, _) => Kodkod.Rel norm_frac_rel
  1186       | Cst (NatToInt, _, Func (Atom _, Atom _)) => Kodkod.Iden
  1295       | Cst (NatToInt, Type ("fun", [@{typ nat}, _]), Func (Atom _, Atom _)) =>
  1187       | Cst (NatToInt, _,
  1296         Kodkod.Iden
       
  1297       | Cst (NatToInt, Type ("fun", [@{typ nat}, _]),
  1188              Func (Atom (nat_k, nat_j0), Opt (Atom (int_k, int_j0)))) =>
  1298              Func (Atom (nat_k, nat_j0), Opt (Atom (int_k, int_j0)))) =>
  1189         if nat_j0 = int_j0 then
  1299         if nat_j0 = int_j0 then
  1190           kk_intersect Kodkod.Iden
  1300           kk_intersect Kodkod.Iden
  1191               (kk_product (Kodkod.AtomSeq (max_int_for_card int_k + 1, nat_j0))
  1301               (kk_product (Kodkod.AtomSeq (max_int_for_card int_k + 1, nat_j0))
  1192                           Kodkod.Univ)
  1302                           Kodkod.Univ)
  1193         else
  1303         else
  1194           raise BAD ("Nitpick_Kodkod.to_r (NatToInt)", "\"nat_j0 <> int_j0\"")
  1304           raise BAD ("Nitpick_Kodkod.to_r (NatToInt)", "\"nat_j0 <> int_j0\"")
  1195       | Cst (IntToNat, _, Func (Atom (int_k, int_j0), nat_R)) =>
  1305       | Cst (NatToInt, T as Type ("fun", [@{typ "unsigned_bit word"}, _]), R) =>
       
  1306         to_bit_word_unary_op T R I
       
  1307       | Cst (IntToNat, Type ("fun", [@{typ int}, _]),
       
  1308              Func (Atom (int_k, int_j0), nat_R)) =>
  1196         let
  1309         let
  1197           val abs_card = max_int_for_card int_k + 1
  1310           val abs_card = max_int_for_card int_k + 1
  1198           val (nat_k, nat_j0) = the_single (atom_schema_of_rep nat_R)
  1311           val (nat_k, nat_j0) = the_single (atom_schema_of_rep nat_R)
  1199           val overlap = Int.min (nat_k, abs_card)
  1312           val overlap = Int.min (nat_k, abs_card)
  1200         in
  1313         in
  1206                           (kk_product (Kodkod.AtomSeq (overlap, int_j0))
  1319                           (kk_product (Kodkod.AtomSeq (overlap, int_j0))
  1207                                       Kodkod.Univ))
  1320                                       Kodkod.Univ))
  1208           else
  1321           else
  1209             raise BAD ("Nitpick_Kodkod.to_r (IntToNat)", "\"nat_j0 <> int_j0\"")
  1322             raise BAD ("Nitpick_Kodkod.to_r (IntToNat)", "\"nat_j0 <> int_j0\"")
  1210         end
  1323         end
       
  1324       | Cst (IntToNat, T as Type ("fun", [@{typ "signed_bit word"}, _]), R) =>
       
  1325         to_bit_word_unary_op T R
       
  1326             (fn i => Kodkod.IntIf (Kodkod.LE (i, Kodkod.Num 0),
       
  1327                                    Kodkod.Num 0, i))
  1211       | Op1 (Not, _, R, u1) => kk_not3 (to_rep R u1)
  1328       | Op1 (Not, _, R, u1) => kk_not3 (to_rep R u1)
  1212       | Op1 (Finite, _, Opt (Atom _), _) => Kodkod.None
  1329       | Op1 (Finite, _, Opt (Atom _), _) => Kodkod.None
  1213       | Op1 (Converse, T, R, u1) =>
  1330       | Op1 (Converse, T, R, u1) =>
  1214         let
  1331         let
  1215           val (b_T, a_T) = HOLogic.dest_prodT (domain_type T)
  1332           val (b_T, a_T) = HOLogic.dest_prodT (domain_type T)
  1239           let
  1356           let
  1240             val T1 = type_of u1
  1357             val T1 = type_of u1
  1241             val R' = rep_to_binary_rel_rep ofs T1 (unopt_rep (rep_of u1))
  1358             val R' = rep_to_binary_rel_rep ofs T1 (unopt_rep (rep_of u1))
  1242             val R'' = opt_rep ofs T1 R'
  1359             val R'' = opt_rep ofs T1 R'
  1243           in
  1360           in
  1244             single_rel_let kk
  1361             single_rel_rel_let kk
  1245                 (fn r =>
  1362                 (fn r =>
  1246                     let
  1363                     let
  1247                       val true_r = kk_closure (kk_join r true_atom)
  1364                       val true_r = kk_closure (kk_join r true_atom)
  1248                       val full_r = full_rel_for_rep R'
  1365                       val full_r = full_rel_for_rep R'
  1249                       val false_r = kk_difference full_r
  1366                       val false_r = kk_difference full_r
  1264       | Op1 (SingletonSet, _, R, u1) =>
  1381       | Op1 (SingletonSet, _, R, u1) =>
  1265         (case R of
  1382         (case R of
  1266            Func (R1, Formula Neut) => to_rep R1 u1
  1383            Func (R1, Formula Neut) => to_rep R1 u1
  1267          | Func (Unit, Opt R) => to_guard [u1] R true_atom
  1384          | Func (Unit, Opt R) => to_guard [u1] R true_atom
  1268          | Func (R1, R2 as Opt _) =>
  1385          | Func (R1, R2 as Opt _) =>
  1269            single_rel_let kk
  1386            single_rel_rel_let kk
  1270                (fn r => kk_rel_if (kk_no r) (empty_rel_for_rep R)
  1387                (fn r => kk_rel_if (kk_no r) (empty_rel_for_rep R)
  1271                             (rel_expr_to_func kk R1 bool_atom_R
  1388                             (rel_expr_to_func kk R1 bool_atom_R
  1272                                               (Func (R1, Formula Neut)) r))
  1389                                               (Func (R1, Formula Neut)) r))
  1273                (to_opt R1 u1)
  1390                (to_opt R1 u1)
  1274          | _ => raise NUT ("Nitpick_Kodkod.to_r (SingletonSet)", [u]))
  1391          | _ => raise NUT ("Nitpick_Kodkod.to_r (SingletonSet)", [u]))
  1307         else kk_rel_if (to_f u1) true_atom (to_r u2)
  1424         else kk_rel_if (to_f u1) true_atom (to_r u2)
  1308       | Op2 (And, _, _, u1, u2) =>
  1425       | Op2 (And, _, _, u1, u2) =>
  1309         if is_opt_rep (rep_of u1) then kk_rel_if (to_f u2) (to_r u1) false_atom
  1426         if is_opt_rep (rep_of u1) then kk_rel_if (to_f u2) (to_r u1) false_atom
  1310         else kk_rel_if (to_f u1) (to_r u2) false_atom
  1427         else kk_rel_if (to_f u1) (to_r u2) false_atom
  1311       | Op2 (Less, _, _, u1, u2) =>
  1428       | Op2 (Less, _, _, u1, u2) =>
  1312         if type_of u1 = nat_T then
  1429         (case type_of u1 of
  1313           if is_Cst Unrep u1 then to_compare_with_unrep u2 false_atom
  1430            @{typ nat} =>
  1314           else if is_Cst Unrep u2 then to_compare_with_unrep u1 true_atom
  1431            if is_Cst Unrep u1 then to_compare_with_unrep u2 false_atom
  1315           else kk_nat_less (to_integer u1) (to_integer u2)
  1432            else if is_Cst Unrep u2 then to_compare_with_unrep u1 true_atom
  1316         else
  1433            else kk_nat_less (to_integer u1) (to_integer u2)
  1317           kk_int_less (to_integer u1) (to_integer u2)
  1434          | @{typ int} => kk_int_less (to_integer u1) (to_integer u2)
       
  1435          | _ => double_rel_rel_let kk
       
  1436                     (fn r1 => fn r2 =>
       
  1437                         kk_rel_if
       
  1438                             (fold kk_and (map_filter (fn (u, r) =>
       
  1439                                  if is_opt_rep (rep_of u) then SOME (kk_some r)
       
  1440                                  else NONE) [(u1, r1), (u2, r2)]) Kodkod.True)
       
  1441                             (atom_from_formula kk bool_j0 (Kodkod.LT (pairself
       
  1442                                 (int_expr_from_atom kk (type_of u1)) (r1, r2))))
       
  1443                             Kodkod.None)
       
  1444                     (to_r u1) (to_r u2))
  1318       | Op2 (The, T, R, u1, u2) =>
  1445       | Op2 (The, T, R, u1, u2) =>
  1319         if is_opt_rep R then
  1446         if is_opt_rep R then
  1320           let val r1 = to_opt (Func (unopt_rep R, bool_atom_R)) u1 in
  1447           let val r1 = to_opt (Func (unopt_rep R, bool_atom_R)) u1 in
  1321             kk_rel_if (kk_one (kk_join r1 true_atom)) (kk_join r1 true_atom)
  1448             kk_rel_if (kk_one (kk_join r1 true_atom)) (kk_join r1 true_atom)
  1322                       (kk_rel_if (kk_or (kk_some (kk_join r1 true_atom))
  1449                       (kk_rel_if (kk_or (kk_some (kk_join r1 true_atom))
  1466       | Op2 (Apply, @{typ nat}, _,
  1593       | Op2 (Apply, @{typ nat}, _,
  1467              Op2 (Apply, _, _, Cst (Subtract, _, _), u1), u2) =>
  1594              Op2 (Apply, _, _, Cst (Subtract, _, _), u1), u2) =>
  1468         if is_Cst Unrep u2 andalso not (is_opt_rep (rep_of u1)) then
  1595         if is_Cst Unrep u2 andalso not (is_opt_rep (rep_of u1)) then
  1469           Kodkod.Atom (offset_of_type ofs nat_T)
  1596           Kodkod.Atom (offset_of_type ofs nat_T)
  1470         else
  1597         else
  1471           fold kk_join [to_integer u1, to_integer u2] nat_subtract_rel
  1598           fold kk_join (map to_integer [u1, u2]) (Kodkod.Rel nat_subtract_rel)
  1472       | Op2 (Apply, _, R, u1, u2) =>
  1599       | Op2 (Apply, _, R, u1, u2) =>
  1473         if is_Cst Unrep u2 andalso is_set_type (type_of u1)
  1600         if is_Cst Unrep u2 andalso is_set_type (type_of u1)
  1474            andalso is_FreeName u1 then
  1601            andalso is_FreeName u1 then
  1475           false_atom
  1602           false_atom
  1476         else
  1603         else
  1492         end
  1619         end
  1493       | Op3 (Let, _, R, u1, u2, u3) =>
  1620       | Op3 (Let, _, R, u1, u2, u3) =>
  1494         kk_rel_let [to_expr_assign u1 u2] (to_rep R u3)
  1621         kk_rel_let [to_expr_assign u1 u2] (to_rep R u3)
  1495       | Op3 (If, _, R, u1, u2, u3) =>
  1622       | Op3 (If, _, R, u1, u2, u3) =>
  1496         if is_opt_rep (rep_of u1) then
  1623         if is_opt_rep (rep_of u1) then
  1497           triple_rel_let kk
  1624           tripl_rel_rel_let kk
  1498               (fn r1 => fn r2 => fn r3 =>
  1625               (fn r1 => fn r2 => fn r3 =>
  1499                   let val empty_r = empty_rel_for_rep R in
  1626                   let val empty_r = empty_rel_for_rep R in
  1500                     fold1 kk_union
  1627                     fold1 kk_union
  1501                           [kk_rel_if (kk_rel_eq r1 true_atom) r2 empty_r,
  1628                           [kk_rel_if (kk_rel_eq r1 true_atom) r2 empty_r,
  1502                            kk_rel_if (kk_rel_eq r1 false_atom) r3 empty_r,
  1629                            kk_rel_if (kk_rel_eq r1 false_atom) r3 empty_r,
  1684                Opt (Vect (k, Atom _)) => kk_vect_set_op connective k r1 r2
  1811                Opt (Vect (k, Atom _)) => kk_vect_set_op connective k r1 r2
  1685              | Vect (k, Atom _) => kk_vect_set_op connective k r1 r2
  1812              | Vect (k, Atom _) => kk_vect_set_op connective k r1 r2
  1686              | Func (_, Formula Neut) => set_oper r1 r2
  1813              | Func (_, Formula Neut) => set_oper r1 r2
  1687              | Func (Unit, _) => connective3 r1 r2
  1814              | Func (Unit, _) => connective3 r1 r2
  1688              | Func (R1, _) =>
  1815              | Func (R1, _) =>
  1689                double_rel_let kk
  1816                double_rel_rel_let kk
  1690                    (fn r1 => fn r2 =>
  1817                    (fn r1 => fn r2 =>
  1691                        kk_union
  1818                        kk_union
  1692                            (kk_product
  1819                            (kk_product
  1693                                 (true_set_oper (kk_join r1 true_atom)
  1820                                 (true_set_oper (kk_join r1 true_atom)
  1694                                      (kk_join r2 (atom_for_bool bool_j0
  1821                                      (kk_join r2 (atom_for_bool bool_j0
  1699                                      (kk_join r2 (atom_for_bool bool_j0
  1826                                      (kk_join r2 (atom_for_bool bool_j0
  1700                                                                 neg_second)))
  1827                                                                 neg_second)))
  1701                                 false_atom))
  1828                                 false_atom))
  1702                    r1 r2
  1829                    r1 r2
  1703              | _ => raise REP ("Nitpick_Kodkod.to_set_op", [min_R]))
  1830              | _ => raise REP ("Nitpick_Kodkod.to_set_op", [min_R]))
       
  1831       end
       
  1832     (* typ -> rep -> (Kodkod.int_expr -> Kodkod.int_expr) -> Kodkod.rel_expr *)
       
  1833     and to_bit_word_unary_op T R oper =
       
  1834       let
       
  1835         val Ts = strip_type T ||> single |> op @
       
  1836         (* int -> Kodkod.int_expr *)
       
  1837         fun int_arg j = int_expr_from_atom kk (nth Ts j) (Kodkod.Var (1, j))
       
  1838       in
       
  1839         kk_comprehension (decls_for_atom_schema 0 (atom_schema_of_rep R))
       
  1840             (Kodkod.FormulaLet
       
  1841                  (map (fn j => Kodkod.AssignIntReg (j, int_arg j)) (0 upto 1),
       
  1842                   Kodkod.IntEq (Kodkod.IntReg 1, oper (Kodkod.IntReg 0))))
       
  1843       end
       
  1844     (* typ -> rep
       
  1845        -> (Kodkod.int_expr -> Kodkod.int_expr -> Kodkod.int_expr -> bool) option
       
  1846        -> (Kodkod.int_expr -> Kodkod.int_expr -> Kodkod.int_expr) option
       
  1847        -> Kodkod.rel_expr *)
       
  1848     and to_bit_word_binary_op T R opt_guard opt_oper =
       
  1849       let
       
  1850         val Ts = strip_type T ||> single |> op @
       
  1851         (* int -> Kodkod.int_expr *)
       
  1852         fun int_arg j = int_expr_from_atom kk (nth Ts j) (Kodkod.Var (1, j))
       
  1853       in
       
  1854         kk_comprehension (decls_for_atom_schema 0 (atom_schema_of_rep R))
       
  1855             (Kodkod.FormulaLet
       
  1856                  (map (fn j => Kodkod.AssignIntReg (j, int_arg j)) (0 upto 2),
       
  1857                   fold1 kk_and
       
  1858                         ((case opt_guard of
       
  1859                             NONE => []
       
  1860                           | SOME guard =>
       
  1861                             [guard (Kodkod.IntReg 0) (Kodkod.IntReg 1)
       
  1862                                    (Kodkod.IntReg 2)]) @
       
  1863                          (case opt_oper of
       
  1864                             NONE => []
       
  1865                           | SOME oper =>
       
  1866                             [Kodkod.IntEq (Kodkod.IntReg 2,
       
  1867                                  oper (Kodkod.IntReg 0) (Kodkod.IntReg 1))]))))
  1704       end
  1868       end
  1705     (* rep -> rep -> Kodkod.rel_expr -> nut -> Kodkod.rel_expr *)
  1869     (* rep -> rep -> Kodkod.rel_expr -> nut -> Kodkod.rel_expr *)
  1706     and to_apply res_R func_u arg_u =
  1870     and to_apply res_R func_u arg_u =
  1707       case unopt_rep (rep_of func_u) of
  1871       case unopt_rep (rep_of func_u) of
  1708         Unit =>
  1872         Unit =>