src/HOL/Tools/Nitpick/nitpick_rep.ML
changeset 38190 b02e204b613a
parent 37678 0040bafffdef
child 39345 062c10ff848c
equal deleted inserted replaced
38189:a493dc2179a3 38190:b02e204b613a
    11   type scope = Nitpick_Scope.scope
    11   type scope = Nitpick_Scope.scope
    12 
    12 
    13   datatype rep =
    13   datatype rep =
    14     Any |
    14     Any |
    15     Formula of polarity |
    15     Formula of polarity |
    16     Unit |
       
    17     Atom of int * int |
    16     Atom of int * int |
    18     Struct of rep list |
    17     Struct of rep list |
    19     Vect of int * rep |
    18     Vect of int * rep |
    20     Func of rep * rep |
    19     Func of rep * rep |
    21     Opt of rep
    20     Opt of rep
    66 open Nitpick_Scope
    65 open Nitpick_Scope
    67 
    66 
    68 datatype rep =
    67 datatype rep =
    69   Any |
    68   Any |
    70   Formula of polarity |
    69   Formula of polarity |
    71   Unit |
       
    72   Atom of int * int |
    70   Atom of int * int |
    73   Struct of rep list |
    71   Struct of rep list |
    74   Vect of int * rep |
    72   Vect of int * rep |
    75   Func of rep * rep |
    73   Func of rep * rep |
    76   Opt of rep
    74   Opt of rep
    86     if String.isPrefix "[" s orelse not (is_substring_of " " s) then s
    84     if String.isPrefix "[" s orelse not (is_substring_of " " s) then s
    87     else "(" ^ s ^ ")"
    85     else "(" ^ s ^ ")"
    88   end
    86   end
    89 and string_for_rep Any = "X"
    87 and string_for_rep Any = "X"
    90   | string_for_rep (Formula polar) = "F" ^ string_for_polarity polar
    88   | string_for_rep (Formula polar) = "F" ^ string_for_polarity polar
    91   | string_for_rep Unit = "U"
       
    92   | string_for_rep (Atom (k, j0)) =
    89   | string_for_rep (Atom (k, j0)) =
    93     "A" ^ string_of_int k ^ (if j0 = 0 then "" else "@" ^ string_of_int j0)
    90     "A" ^ string_of_int k ^ (if j0 = 0 then "" else "@" ^ string_of_int j0)
    94   | string_for_rep (Struct rs) = "[" ^ commas (map string_for_rep rs) ^ "]"
    91   | string_for_rep (Struct rs) = "[" ^ commas (map string_for_rep rs) ^ "]"
    95   | string_for_rep (Vect (k, R)) =
    92   | string_for_rep (Vect (k, R)) =
    96     string_of_int k ^ " x " ^ atomic_string_for_rep R
    93     string_of_int k ^ " x " ^ atomic_string_for_rep R
   106   | is_opt_rep (Opt _) = true
   103   | is_opt_rep (Opt _) = true
   107   | is_opt_rep _ = false
   104   | is_opt_rep _ = false
   108 
   105 
   109 fun card_of_rep Any = raise REP ("Nitpick_Rep.card_of_rep", [Any])
   106 fun card_of_rep Any = raise REP ("Nitpick_Rep.card_of_rep", [Any])
   110   | card_of_rep (Formula _) = 2
   107   | card_of_rep (Formula _) = 2
   111   | card_of_rep Unit = 1
       
   112   | card_of_rep (Atom (k, _)) = k
   108   | card_of_rep (Atom (k, _)) = k
   113   | card_of_rep (Struct rs) = Integer.prod (map card_of_rep rs)
   109   | card_of_rep (Struct rs) = Integer.prod (map card_of_rep rs)
   114   | card_of_rep (Vect (k, R)) = reasonable_power (card_of_rep R) k
   110   | card_of_rep (Vect (k, R)) = reasonable_power (card_of_rep R) k
   115   | card_of_rep (Func (R1, R2)) =
   111   | card_of_rep (Func (R1, R2)) =
   116     reasonable_power (card_of_rep R2) (card_of_rep R1)
   112     reasonable_power (card_of_rep R2) (card_of_rep R1)
   117   | card_of_rep (Opt R) = card_of_rep R
   113   | card_of_rep (Opt R) = card_of_rep R
   118 fun arity_of_rep Any = raise REP ("Nitpick_Rep.arity_of_rep", [Any])
   114 fun arity_of_rep Any = raise REP ("Nitpick_Rep.arity_of_rep", [Any])
   119   | arity_of_rep (Formula _) = 0
   115   | arity_of_rep (Formula _) = 0
   120   | arity_of_rep Unit = 0
       
   121   | arity_of_rep (Atom _) = 1
   116   | arity_of_rep (Atom _) = 1
   122   | arity_of_rep (Struct Rs) = Integer.sum (map arity_of_rep Rs)
   117   | arity_of_rep (Struct Rs) = Integer.sum (map arity_of_rep Rs)
   123   | arity_of_rep (Vect (k, R)) = k * arity_of_rep R
   118   | arity_of_rep (Vect (k, R)) = k * arity_of_rep R
   124   | arity_of_rep (Func (R1, R2)) = arity_of_rep R1 + arity_of_rep R2
   119   | arity_of_rep (Func (R1, R2)) = arity_of_rep R1 + arity_of_rep R2
   125   | arity_of_rep (Opt R) = arity_of_rep R
   120   | arity_of_rep (Opt R) = arity_of_rep R
   126 fun min_univ_card_of_rep Any =
   121 fun min_univ_card_of_rep Any =
   127     raise REP ("Nitpick_Rep.min_univ_card_of_rep", [Any])
   122     raise REP ("Nitpick_Rep.min_univ_card_of_rep", [Any])
   128   | min_univ_card_of_rep (Formula _) = 0
   123   | min_univ_card_of_rep (Formula _) = 0
   129   | min_univ_card_of_rep Unit = 0
       
   130   | min_univ_card_of_rep (Atom (k, j0)) = k + j0 + 1
   124   | min_univ_card_of_rep (Atom (k, j0)) = k + j0 + 1
   131   | min_univ_card_of_rep (Struct Rs) =
   125   | min_univ_card_of_rep (Struct Rs) =
   132     fold Integer.max (map min_univ_card_of_rep Rs) 0
   126     fold Integer.max (map min_univ_card_of_rep Rs) 0
   133   | min_univ_card_of_rep (Vect (_, R)) = min_univ_card_of_rep R
   127   | min_univ_card_of_rep (Vect (_, R)) = min_univ_card_of_rep R
   134   | min_univ_card_of_rep (Func (R1, R2)) =
   128   | min_univ_card_of_rep (Func (R1, R2)) =
   135     Int.max (min_univ_card_of_rep R1, min_univ_card_of_rep R2)
   129     Int.max (min_univ_card_of_rep R1, min_univ_card_of_rep R2)
   136   | min_univ_card_of_rep (Opt R) = min_univ_card_of_rep R
   130   | min_univ_card_of_rep (Opt R) = min_univ_card_of_rep R
   137 
   131 
   138 fun is_one_rep Unit = true
   132 fun is_one_rep (Atom _) = true
   139   | is_one_rep (Atom _) = true
       
   140   | is_one_rep (Struct _) = true
   133   | is_one_rep (Struct _) = true
   141   | is_one_rep (Vect _) = true
   134   | is_one_rep (Vect _) = true
   142   | is_one_rep _ = false
   135   | is_one_rep _ = false
   143 fun is_lone_rep (Opt R) = is_one_rep R
   136 fun is_lone_rep (Opt R) = is_one_rep R
   144   | is_lone_rep R = is_one_rep R
   137   | is_lone_rep R = is_one_rep R
   145 
   138 
   146 fun dest_Func (Func z) = z
   139 fun dest_Func (Func z) = z
   147   | dest_Func R = raise REP ("Nitpick_Rep.dest_Func", [R])
   140   | dest_Func R = raise REP ("Nitpick_Rep.dest_Func", [R])
   148 fun lazy_range_rep _ _ _ Unit = Unit
   141 fun lazy_range_rep _ _ _ (Vect (_, R)) = R
   149   | lazy_range_rep _ _ _ (Vect (_, R)) = R
       
   150   | lazy_range_rep _ _ _ (Func (_, R2)) = R2
   142   | lazy_range_rep _ _ _ (Func (_, R2)) = R2
   151   | lazy_range_rep ofs T ran_card (Opt R) =
   143   | lazy_range_rep ofs T ran_card (Opt R) =
   152     Opt (lazy_range_rep ofs T ran_card R)
   144     Opt (lazy_range_rep ofs T ran_card R)
   153   | lazy_range_rep ofs (Type (@{type_name fun}, [_, T2])) _ (Atom (1, _)) =
   145   | lazy_range_rep ofs (Type (@{type_name fun}, [_, T2])) _ (Atom (1, _)) =
   154     Atom (1, offset_of_type ofs T2)
   146     Atom (1, offset_of_type ofs T2)
   199   | min_rep _ (Opt R) = Opt R
   191   | min_rep _ (Opt R) = Opt R
   200   | min_rep (Formula polar1) (Formula polar2) =
   192   | min_rep (Formula polar1) (Formula polar2) =
   201     Formula (min_polarity polar1 polar2)
   193     Formula (min_polarity polar1 polar2)
   202   | min_rep (Formula polar) _ = Formula polar
   194   | min_rep (Formula polar) _ = Formula polar
   203   | min_rep _ (Formula polar) = Formula polar
   195   | min_rep _ (Formula polar) = Formula polar
   204   | min_rep Unit _ = Unit
       
   205   | min_rep _ Unit = Unit
       
   206   | min_rep (Atom x) _ = Atom x
   196   | min_rep (Atom x) _ = Atom x
   207   | min_rep _ (Atom x) = Atom x
   197   | min_rep _ (Atom x) = Atom x
   208   | min_rep (Struct Rs1) (Struct Rs2) = Struct (min_reps Rs1 Rs2)
   198   | min_rep (Struct Rs1) (Struct Rs2) = Struct (min_reps Rs1 Rs2)
   209   | min_rep (Struct Rs) _ = Struct Rs
   199   | min_rep (Struct Rs) _ = Struct Rs
   210   | min_rep _ (Struct Rs) = Struct Rs
   200   | min_rep _ (Struct Rs) = Struct Rs
   229     else if min_rep R1 R2 = R1 then R1 :: Rs1
   219     else if min_rep R1 R2 = R1 then R1 :: Rs1
   230     else R2 :: Rs2
   220     else R2 :: Rs2
   231 
   221 
   232 fun card_of_domain_from_rep ran_card R =
   222 fun card_of_domain_from_rep ran_card R =
   233   case R of
   223   case R of
   234     Unit => 1
   224     Atom (k, _) => exact_log ran_card k
   235   | Atom (k, _) => exact_log ran_card k
       
   236   | Vect (k, _) => k
   225   | Vect (k, _) => k
   237   | Func (R1, _) => card_of_rep R1
   226   | Func (R1, _) => card_of_rep R1
   238   | Opt R => card_of_domain_from_rep ran_card R
   227   | Opt R => card_of_domain_from_rep ran_card R
   239   | _ => raise REP ("Nitpick_Rep.card_of_domain_from_rep", [R])
   228   | _ => raise REP ("Nitpick_Rep.card_of_domain_from_rep", [R])
   240 
   229 
   244     val j0 = offset_of_type ofs (fst (HOLogic.dest_prodT (domain_type T)))
   233     val j0 = offset_of_type ofs (fst (HOLogic.dest_prodT (domain_type T)))
   245   in Func (Struct [Atom (k, j0), Atom (k, j0)], Formula Neut) end
   234   in Func (Struct [Atom (k, j0), Atom (k, j0)], Formula Neut) end
   246 
   235 
   247 fun best_one_rep_for_type (scope as {card_assigns, ...} : scope)
   236 fun best_one_rep_for_type (scope as {card_assigns, ...} : scope)
   248                           (Type (@{type_name fun}, [T1, T2])) =
   237                           (Type (@{type_name fun}, [T1, T2])) =
   249     (case best_one_rep_for_type scope T2 of
   238     Vect (card_of_type card_assigns T1, (best_one_rep_for_type scope T2))
   250        Unit => Unit
   239   | best_one_rep_for_type scope (Type (@{type_name prod}, Ts)) =
   251      | R2 => Vect (card_of_type card_assigns T1, R2))
   240     Struct (map (best_one_rep_for_type scope) Ts)
   252   | best_one_rep_for_type scope (Type (@{type_name Product_Type.prod}, [T1, T2])) =
       
   253     (case (best_one_rep_for_type scope T1, best_one_rep_for_type scope T2) of
       
   254        (Unit, Unit) => Unit
       
   255      | (R1, R2) => Struct [R1, R2])
       
   256   | best_one_rep_for_type {card_assigns, datatypes, ofs, ...} T =
   241   | best_one_rep_for_type {card_assigns, datatypes, ofs, ...} T =
   257     (case card_of_type card_assigns T of
   242     Atom (card_of_type card_assigns T, offset_of_type ofs T)
   258        1 => if is_some (datatype_spec datatypes T) orelse
   243 
   259                is_iterator_type T then
       
   260               Atom (1, offset_of_type ofs T)
       
   261             else
       
   262               Unit
       
   263      | k => Atom (k, offset_of_type ofs T))
       
   264 
       
   265 (* Datatypes are never represented by Unit, because it would confuse
       
   266    "nfa_transitions_for_ctor". *)
       
   267 fun best_opt_set_rep_for_type scope (Type (@{type_name fun}, [T1, T2])) =
   244 fun best_opt_set_rep_for_type scope (Type (@{type_name fun}, [T1, T2])) =
   268     Func (best_one_rep_for_type scope T1, best_opt_set_rep_for_type scope T2)
   245     Func (best_one_rep_for_type scope T1, best_opt_set_rep_for_type scope T2)
   269   | best_opt_set_rep_for_type (scope as {ofs, ...}) T =
   246   | best_opt_set_rep_for_type (scope as {ofs, ...}) T =
   270     opt_rep ofs T (best_one_rep_for_type scope T)
   247     opt_rep ofs T (best_one_rep_for_type scope T)
   271 fun best_non_opt_set_rep_for_type (scope as {ofs, ...})
   248 fun best_non_opt_set_rep_for_type (scope as {ofs, ...})
   272                                   (Type (@{type_name fun}, [T1, T2])) =
   249                                   (Type (@{type_name fun}, [T1, T2])) =
   273     (case (best_one_rep_for_type scope T1,
   250     (case (best_one_rep_for_type scope T1,
   274            best_non_opt_set_rep_for_type scope T2) of
   251            best_non_opt_set_rep_for_type scope T2) of
   275        (_, Unit) => Unit
   252        (R1, Atom (2, _)) => Func (R1, Formula Neut)
   276      | (Unit, Atom (2, _)) =>
       
   277        Func (Atom (1, offset_of_type ofs T1), Formula Neut)
       
   278      | (R1, Atom (2, _)) => Func (R1, Formula Neut)
       
   279      | z => Func z)
   253      | z => Func z)
   280   | best_non_opt_set_rep_for_type scope T = best_one_rep_for_type scope T
   254   | best_non_opt_set_rep_for_type scope T = best_one_rep_for_type scope T
   281 fun best_set_rep_for_type (scope as {datatypes, ...}) T =
   255 fun best_set_rep_for_type (scope as {datatypes, ...}) T =
   282   (if is_exact_type datatypes true T then best_non_opt_set_rep_for_type
   256   (if is_exact_type datatypes true T then best_non_opt_set_rep_for_type
   283    else best_opt_set_rep_for_type) scope T
   257    else best_opt_set_rep_for_type) scope T
   288   | best_non_opt_symmetric_reps_for_fun_type _ T =
   262   | best_non_opt_symmetric_reps_for_fun_type _ T =
   289     raise TYPE ("Nitpick_Rep.best_non_opt_symmetric_reps_for_fun_type", [T], [])
   263     raise TYPE ("Nitpick_Rep.best_non_opt_symmetric_reps_for_fun_type", [T], [])
   290 
   264 
   291 fun atom_schema_of_rep Any = raise REP ("Nitpick_Rep.atom_schema_of_rep", [Any])
   265 fun atom_schema_of_rep Any = raise REP ("Nitpick_Rep.atom_schema_of_rep", [Any])
   292   | atom_schema_of_rep (Formula _) = []
   266   | atom_schema_of_rep (Formula _) = []
   293   | atom_schema_of_rep Unit = []
       
   294   | atom_schema_of_rep (Atom x) = [x]
   267   | atom_schema_of_rep (Atom x) = [x]
   295   | atom_schema_of_rep (Struct Rs) = atom_schema_of_reps Rs
   268   | atom_schema_of_rep (Struct Rs) = atom_schema_of_reps Rs
   296   | atom_schema_of_rep (Vect (k, R)) = replicate_list k (atom_schema_of_rep R)
   269   | atom_schema_of_rep (Vect (k, R)) = replicate_list k (atom_schema_of_rep R)
   297   | atom_schema_of_rep (Func (R1, R2)) =
   270   | atom_schema_of_rep (Func (R1, R2)) =
   298     atom_schema_of_rep R1 @ atom_schema_of_rep R2
   271     atom_schema_of_rep R1 @ atom_schema_of_rep R2
   299   | atom_schema_of_rep (Opt R) = atom_schema_of_rep R
   272   | atom_schema_of_rep (Opt R) = atom_schema_of_rep R
   300 and atom_schema_of_reps Rs = maps atom_schema_of_rep Rs
   273 and atom_schema_of_reps Rs = maps atom_schema_of_rep Rs
   301 
   274 
   302 fun type_schema_of_rep _ (Formula _) = []
   275 fun type_schema_of_rep _ (Formula _) = []
   303   | type_schema_of_rep _ Unit = []
       
   304   | type_schema_of_rep T (Atom _) = [T]
   276   | type_schema_of_rep T (Atom _) = [T]
   305   | type_schema_of_rep (Type (@{type_name Product_Type.prod}, [T1, T2])) (Struct [R1, R2]) =
   277   | type_schema_of_rep (Type (@{type_name prod}, [T1, T2])) (Struct [R1, R2]) =
   306     type_schema_of_reps [T1, T2] [R1, R2]
   278     type_schema_of_reps [T1, T2] [R1, R2]
   307   | type_schema_of_rep (Type (@{type_name fun}, [_, T2])) (Vect (k, R)) =
   279   | type_schema_of_rep (Type (@{type_name fun}, [_, T2])) (Vect (k, R)) =
   308     replicate_list k (type_schema_of_rep T2 R)
   280     replicate_list k (type_schema_of_rep T2 R)
   309   | type_schema_of_rep (Type (@{type_name fun}, [T1, T2])) (Func (R1, R2)) =
   281   | type_schema_of_rep (Type (@{type_name fun}, [T1, T2])) (Func (R1, R2)) =
   310     type_schema_of_rep T1 R1 @ type_schema_of_rep T2 R2
   282     type_schema_of_rep T1 R1 @ type_schema_of_rep T2 R2