1structure intSyntax :> intSyntax = 2struct 3 4open HolKernel boolLib Parse integerTheory; 5 6val ERR = mk_HOL_ERR "intSyntax"; 7 8val num_ty = numSyntax.num 9val int_ty = mk_thy_type{Tyop = "int", Thy="integer", Args = []} 10 11fun Const s = prim_mk_const{Name=s, Thy="integer"}; 12 13val negate_tm = Const "int_neg" 14val plus_tm = Const "int_add" 15val minus_tm = Const "int_sub" 16val mult_tm = Const "int_mul" 17val exp_tm = Const "int_exp" 18val div_tm = Const "int_div" 19val mod_tm = Const "int_mod" 20val quot_tm = Const "int_quot" 21val rem_tm = Const "int_rem" 22val less_tm = Const "int_lt" 23val leq_tm = Const "int_le" 24val greater_tm = Const "int_gt" 25val geq_tm = Const "int_ge" 26val min_tm = Const "int_min" 27val max_tm = Const "int_max"; 28val absval_tm = Const "ABS" 29val divides_tm = Const "int_divides" 30val LEAST_INT_tm = Const "LEAST_INT" 31val int_injection = Const "int_of_num" 32val Num_tm = Const "Num" 33 34val int_eq_tm = inst [alpha |-> int_ty] boolSyntax.equality 35 36fun dest_binop t (srcf,msg) tm = let 37 val (farg1, arg2) = dest_comb tm 38 val (f, arg1) = dest_comb farg1 39in 40 if f !~ t then raise ERR srcf msg 41 else (arg1, arg2) 42end 43 44val dest_plus = dest_binop plus_tm ("dest_plus", "Term not a plus") 45val is_plus = can dest_plus 46fun mk_plus (arg1, arg2) = list_mk_comb(plus_tm, [arg1, arg2]) 47 48fun list_mk_plus summands = let 49 fun recurse acc [] = acc 50 | recurse acc (x::xs) = recurse (mk_plus(acc, x)) xs 51in 52 recurse (hd summands) (tl summands) 53 handle List.Empty => raise ERR "list_mk_plus" "empty summand list" 54end 55 56fun strip_plus tm = let 57 fun recurse acc tm = let 58 val (l,r) = dest_plus tm 59 in 60 recurse (recurse acc r) l 61 end handle HOL_ERR _ => tm::acc 62in 63 recurse [] tm 64end 65 66val dest_minus = dest_binop minus_tm ("dest_minus", "Term not a minus") 67val is_minus = can dest_minus 68fun mk_minus (tm1, tm2) = list_mk_comb(minus_tm, [tm1, tm2]) 69 70val dest_mult = dest_binop mult_tm ("dest_mult", "Term not a multiplication") 71val is_mult = can dest_mult 72fun mk_mult (tm1, tm2) = list_mk_comb(mult_tm, [tm1, tm2]); 73 74fun list_mk_mult multiplicands = let 75 fun recurse acc [] = acc 76 | recurse acc (x::xs) = recurse (mk_mult(acc, x)) xs 77in 78 recurse (hd multiplicands) (tl multiplicands) 79 handle List.Empty => raise ERR "list_mk_mult" "empty multiplicand list" 80end 81fun strip_mult tm = let 82 fun recurse acc tm = let 83 val (l,r) = dest_mult tm 84 in 85 recurse (recurse acc r) l 86 end handle HOL_ERR _ => tm::acc 87in 88 recurse [] tm 89end 90 91val dest_exp = dest_binop exp_tm ("dest_exp", "Term not an exp") 92val is_exp = can dest_exp 93fun mk_exp (arg1, arg2) = list_mk_comb(exp_tm, [arg1, arg2]) 94 95val dest_div = dest_binop div_tm ("dest_div", "Term not a division") 96val is_div = can dest_div 97fun mk_div (t1, t2) = list_mk_comb(div_tm, [t1, t2]) 98 99val dest_mod = dest_binop mod_tm ("dest_mod", "Term not a modulo") 100val is_mod = can dest_mod 101fun mk_mod (t1, t2) = list_mk_comb(mod_tm, [t1, t2]) 102 103val dest_quot = dest_binop quot_tm ("dest_quot", "Term not a quotient") 104val is_quot = can dest_quot 105fun mk_quot (t1, t2) = list_mk_comb(quot_tm, [t1, t2]) 106 107val dest_rem = dest_binop rem_tm ("dest_rem", "Term not a remainder") 108val is_rem = can dest_rem 109fun mk_rem (t1, t2) = list_mk_comb(rem_tm, [t1, t2]) 110 111fun mk_absval tm = mk_comb(absval_tm, tm) 112fun dest_absval tm = let 113 val (f,x) = dest_comb tm 114 handle HOL_ERR _ => raise ERR "dest_absval" "term not an absolute value" 115in 116 if same_const f absval_tm then x 117 else raise ERR "dest_absval" "term not an absolute value" 118end 119val is_absval = can dest_absval 120 121fun mk_Num t = mk_comb(Num_tm, t) 122fun dest_Num t = let 123 val (f,x) = dest_comb t 124 handle HOL_ERR _ => raise ERR "dest_Num" "term not a Num coercion" 125in 126 if same_const f Num_tm then x 127 else raise ERR "dest_Num" "term not a Num coercion" 128end 129val is_Num = can dest_Num 130 131 132 133val dest_less = dest_binop less_tm ("dest_less", "Term not a less-than") 134val is_less = can dest_less 135fun mk_less (tm1, tm2) = list_mk_comb(less_tm, [tm1, tm2]) 136 137val dest_leq = dest_binop leq_tm ("dest_leq", "Term not a less-than-or-equal") 138val is_leq = can dest_leq 139fun mk_leq (tm1, tm2) = list_mk_comb(leq_tm, [tm1, tm2]) 140 141val dest_greater = dest_binop greater_tm ("dest_greater", "Term not a greater-than") 142val is_greater = can dest_greater 143fun mk_greater (tm1, tm2) = list_mk_comb(greater_tm, [tm1, tm2]) 144 145val dest_geq = dest_binop geq_tm ("dest_geq", 146 "Term not a greater-than-or-equal") 147val is_geq = can dest_geq 148fun mk_geq (tm1, tm2) = list_mk_comb(geq_tm, [tm1, tm2]) 149 150 151val dest_divides = dest_binop divides_tm ("dest_divides", "Term not a divides") 152val is_divides = can dest_divides 153fun mk_divides (tm1, tm2) = list_mk_comb(divides_tm, [tm1, tm2]) 154 155val dest_min = dest_binop min_tm ("dest_min", "Term not a min") 156val is_min = can dest_min 157fun mk_min (tm1, tm2) = list_mk_comb(min_tm, [tm1, tm2]) 158 159val dest_max = dest_binop max_tm ("dest_max", "Term not a max") 160val is_max = can dest_max 161fun mk_max (tm1, tm2) = list_mk_comb(max_tm, [tm1, tm2]) 162 163fun dest_LEAST_INT t = 164 let 165 val (f, x) = dest_comb t 166 val _ = assert (same_const LEAST_INT_tm) f 167 in 168 x 169 end handle HOL_ERR _ => 170 raise ERR "dest_LEAST_INT" "term not a LEAST_INT" 171 172val is_LEAST_INT = can dest_LEAST_INT 173fun mk_LEAST_INT t = mk_comb (LEAST_INT_tm, t) 174 175fun dest_injected tm = let 176 val (f,x) = dest_comb tm 177 handle HOL_ERR _ => raise ERR "dest_injected" "term not an injection" 178in 179 if f ~~ int_injection then x 180 else raise ERR "dest_injected" "term not an injection" 181end 182val is_injected = can dest_injected 183fun mk_injected tm = mk_comb(int_injection, tm) 184 185 186fun dest_negated tm = let 187 val (l,r) = dest_comb tm 188 handle HOL_ERR _ => raise ERR "dest_negated" "term not a negation" 189in 190 if l ~~ negate_tm then r 191 else raise ERR "dest_negated" "term not a negation" 192end 193val is_negated = can dest_negated 194fun mk_negated tm = mk_comb(negate_tm, tm) 195 196fun is_int_literal t = 197 (rator t ~~ int_injection andalso numSyntax.is_numeral (rand t)) orelse 198 (rator t ~~ negate_tm andalso is_int_literal (rand t)) 199 handle HOL_ERR _ => false 200 201fun int_of_term tm = let 202 val _ = 203 is_int_literal tm orelse 204 raise ERR "int_of_term" "applied to non-literal" 205 val (l,r) = dest_comb tm 206in 207 if l ~~ negate_tm then Arbint.~(int_of_term r) 208 else Arbint.fromNat (numSyntax.dest_numeral r) 209end 210 211fun term_of_int i = let 212 open Arbint 213in 214 if i < zero then 215 mk_negated (term_of_int (~i)) 216 else 217 mk_comb(int_injection, numSyntax.mk_numeral (toNat i)) 218end 219 220val zero_tm = term_of_int Arbint.zero 221val one_tm = term_of_int Arbint.one 222 223end 224