src/Tools/Argo/argo_expr.ML
changeset 63960 3daf02070be5
child 63992 3aa9837d05c7
equal deleted inserted replaced
63959:f77dca1abf1b 63960:3daf02070be5
       
     1 (*  Title:      Tools/Argo/sid_expr.ML
       
     2     Author:     Sascha Boehme
       
     3 
       
     4 The input language of the Argo solver.
       
     5 *)
       
     6 
       
     7 signature ARGO_EXPR =
       
     8 sig
       
     9   (* data types *)
       
    10   datatype typ = Bool | Real | Func of typ * typ | Type of string
       
    11   datatype kind =
       
    12     True | False | Not | And | Or | Imp | Iff | Ite | Eq | App | Con of string * typ |
       
    13     Le | Lt | Num of Rat.rat | Neg | Add | Sub | Mul | Div | Min | Max | Abs
       
    14   datatype expr = E of kind * expr list
       
    15 
       
    16   (* indices, equalities, orders *)
       
    17   val int_of_kind: kind -> int
       
    18   val con_ord: (string * typ) * (string * typ) -> order
       
    19   val eq_kind: kind * kind -> bool
       
    20   val kind_ord: kind * kind -> order
       
    21   val eq_expr: expr * expr -> bool
       
    22   val expr_ord: expr * expr -> order
       
    23   val dual_expr: expr -> expr -> bool
       
    24 
       
    25   (* constructors *)
       
    26   val kind_of_string: string -> kind
       
    27   val true_expr: expr
       
    28   val false_expr: expr
       
    29   val mk_not: expr -> expr
       
    30   val mk_and: expr list -> expr
       
    31   val mk_and2: expr -> expr -> expr
       
    32   val mk_or: expr list -> expr
       
    33   val mk_or2: expr -> expr -> expr
       
    34   val mk_imp: expr -> expr -> expr
       
    35   val mk_iff: expr -> expr -> expr
       
    36   val mk_ite: expr -> expr -> expr -> expr
       
    37   val mk_eq: expr -> expr -> expr
       
    38   val mk_app: expr -> expr -> expr
       
    39   val mk_con: string * typ -> expr
       
    40   val mk_le: expr -> expr -> expr
       
    41   val mk_lt: expr -> expr -> expr
       
    42   val mk_num: Rat.rat -> expr
       
    43   val mk_neg: expr -> expr
       
    44   val mk_add: expr list -> expr
       
    45   val mk_add2: expr -> expr -> expr
       
    46   val mk_sub: expr -> expr -> expr
       
    47   val mk_mul: expr -> expr -> expr
       
    48   val mk_div: expr -> expr -> expr
       
    49   val mk_min: expr -> expr -> expr
       
    50   val mk_max: expr -> expr -> expr
       
    51   val mk_abs: expr -> expr
       
    52 
       
    53   (* type checking *)
       
    54   exception TYPE of expr
       
    55   exception EXPR of expr
       
    56   val type_of: expr -> typ (* raises EXPR *)
       
    57   val check: expr -> bool (* raises TYPE and EXPR *)
       
    58 end
       
    59 
       
    60 structure Argo_Expr: ARGO_EXPR =
       
    61 struct
       
    62 
       
    63 (* data types *)
       
    64 
       
    65 datatype typ = Bool | Real | Func of typ * typ | Type of string
       
    66 
       
    67 datatype kind =
       
    68   True | False | Not | And | Or | Imp | Iff | Ite | Eq | App | Con of string * typ |
       
    69   Le | Lt | Num of Rat.rat | Neg | Add | Sub | Mul | Div | Min | Max | Abs
       
    70 
       
    71 datatype expr = E of kind * expr list
       
    72 
       
    73 
       
    74 (* indices, equalities, orders *)
       
    75 
       
    76 fun int_of_type Bool = 0
       
    77   | int_of_type Real = 1
       
    78   | int_of_type (Func _) = 2
       
    79   | int_of_type (Type _) = 3
       
    80 
       
    81 fun int_of_kind True = 0
       
    82   | int_of_kind False = 1
       
    83   | int_of_kind Not = 2
       
    84   | int_of_kind And = 3
       
    85   | int_of_kind Or = 4
       
    86   | int_of_kind Imp = 5
       
    87   | int_of_kind Iff = 6
       
    88   | int_of_kind Ite = 7
       
    89   | int_of_kind Eq = 8
       
    90   | int_of_kind App = 9
       
    91   | int_of_kind (Con _) = 10
       
    92   | int_of_kind Le = 11
       
    93   | int_of_kind Lt = 12
       
    94   | int_of_kind (Num _) = 13
       
    95   | int_of_kind Neg = 14
       
    96   | int_of_kind Add = 15
       
    97   | int_of_kind Sub = 16
       
    98   | int_of_kind Mul = 17
       
    99   | int_of_kind Div = 18
       
   100   | int_of_kind Min = 19
       
   101   | int_of_kind Max = 20
       
   102   | int_of_kind Abs = 21
       
   103 
       
   104 fun eq_type (Bool, Bool) = true
       
   105   | eq_type (Real, Real) = true
       
   106   | eq_type (Func tys1, Func tys2) = eq_pair eq_type eq_type (tys1, tys2)
       
   107   | eq_type (Type n1, Type n2) = (n1 = n2)
       
   108   | eq_type _ = false
       
   109 
       
   110 fun type_ord (Bool, Bool) = EQUAL
       
   111   | type_ord (Real, Real) = EQUAL
       
   112   | type_ord (Type n1, Type n2) = fast_string_ord (n1, n2)
       
   113   | type_ord (Func tys1, Func tys2) = prod_ord type_ord type_ord (tys1, tys2)
       
   114   | type_ord (ty1, ty2) = int_ord (int_of_type ty1, int_of_type ty2)
       
   115 
       
   116 fun eq_con cp = eq_pair (op =) eq_type cp
       
   117 fun con_ord cp = prod_ord fast_string_ord type_ord cp
       
   118 
       
   119 fun eq_kind (Con c1, Con c2) = eq_con (c1, c2)
       
   120   | eq_kind (Num n1, Num n2) = n1 = n2
       
   121   | eq_kind (k1, k2) = (k1 = k2)
       
   122 
       
   123 fun kind_ord (Con c1, Con c2) = con_ord (c1, c2)
       
   124   | kind_ord (Num n1, Num n2) = Rat.ord (n1, n2)
       
   125   | kind_ord (k1, k2) = int_ord (int_of_kind k1, int_of_kind k2)
       
   126 
       
   127 fun eq_expr (E e1, E e2) = eq_pair eq_kind (eq_list eq_expr) (e1, e2)
       
   128 fun expr_ord (E e1, E e2) = prod_ord kind_ord (list_ord expr_ord) (e1, e2)
       
   129 
       
   130 fun dual_expr (E (Not, [e1])) e2 = eq_expr (e1, e2)
       
   131   | dual_expr e1 (E (Not, [e2])) = eq_expr (e1, e2)
       
   132   | dual_expr _ _ = false
       
   133 
       
   134 
       
   135 (* constructors *)
       
   136 
       
   137 val kind_of_string = the o Symtab.lookup (Symtab.make [
       
   138   ("true", True),("false", False), ("not", Not), ("and", And), ("or", Or), ("imp", Imp),
       
   139   ("iff", Iff), ("ite", Ite), ("eq", Eq), ("app", App), ("le", Le), ("lt", Lt), ("neg", Neg),
       
   140   ("add", Add), ("sub", Sub), ("mul", Mul), ("div", Div), ("min", Min), ("max", Max), ("abs", Abs)])
       
   141 
       
   142 val true_expr = E (True, [])
       
   143 val false_expr = E (False, [])
       
   144 fun mk_not e = E (Not, [e])
       
   145 fun mk_and es = E (And, es)
       
   146 fun mk_and2 e1 e2 = mk_and [e1, e2]
       
   147 fun mk_or es = E (Or, es)
       
   148 fun mk_or2 e1 e2 = mk_or [e1, e2]
       
   149 fun mk_imp e1 e2 = E (Imp, [e1, e2])
       
   150 fun mk_iff e1 e2 = E (Iff, [e1, e2])
       
   151 fun mk_ite e1 e2 e3 = E (Ite, [e1, e2, e3])
       
   152 fun mk_eq e1 e2 = E (Eq, [e1, e2])
       
   153 fun mk_app e1 e2 = E (App, [e1, e2])
       
   154 fun mk_con n = E (Con n, [])
       
   155 fun mk_le e1 e2 = E (Le, [e1, e2])
       
   156 fun mk_lt e1 e2 = E (Lt, [e1, e2])
       
   157 fun mk_num r = E (Num r, [])
       
   158 fun mk_neg e = E (Neg, [e])
       
   159 fun mk_add es = E (Add, es)
       
   160 fun mk_add2 e1 e2 = mk_add [e1, e2]
       
   161 fun mk_sub e1 e2 = E (Sub, [e1, e2])
       
   162 fun mk_mul e1 e2 = E (Mul, [e1, e2])
       
   163 fun mk_div e1 e2 = E (Div, [e1, e2])
       
   164 fun mk_min e1 e2 = E (Min, [e1, e2])
       
   165 fun mk_max e1 e2 = E (Max, [e1, e2])
       
   166 fun mk_abs e = E (Abs, [e])
       
   167 
       
   168 
       
   169 (* type checking *)
       
   170 
       
   171 exception TYPE of expr
       
   172 exception EXPR of expr
       
   173 
       
   174 fun dest_func_type _ (Func tys) = tys
       
   175   | dest_func_type e _ = raise TYPE e
       
   176 
       
   177 fun type_of (E (True, _)) = Bool
       
   178   | type_of (E (False, _)) = Bool
       
   179   | type_of (E (Not, _)) = Bool
       
   180   | type_of (E (And, _)) = Bool
       
   181   | type_of (E (Or, _)) = Bool
       
   182   | type_of (E (Imp, _)) = Bool
       
   183   | type_of (E (Iff, _)) = Bool
       
   184   | type_of (E (Ite, [_, e, _])) = type_of e
       
   185   | type_of (E (Eq, _)) = Bool
       
   186   | type_of (E (App, [e, _])) = snd (dest_func_type e (type_of e))
       
   187   | type_of (E (Con (_, ty), _)) = ty
       
   188   | type_of (E (Le, _)) = Bool
       
   189   | type_of (E (Lt, _)) = Bool
       
   190   | type_of (E (Num _, _)) = Real
       
   191   | type_of (E (Neg, _)) = Real
       
   192   | type_of (E (Add, _)) = Real
       
   193   | type_of (E (Sub, _)) = Real
       
   194   | type_of (E (Mul, _)) = Real
       
   195   | type_of (E (Div, _)) = Real
       
   196   | type_of (E (Min, _)) = Real
       
   197   | type_of (E (Max, _)) = Real
       
   198   | type_of (E (Abs, _)) = Real
       
   199   | type_of e = raise EXPR e
       
   200 
       
   201 fun all_type ty (E (_, es)) = forall (curry eq_type ty o type_of) es
       
   202 val all_bool = all_type Bool
       
   203 val all_real = all_type Real
       
   204 
       
   205 (*
       
   206   Types as well as proper arities are checked.
       
   207   Exception TYPE is raised for invalid types.
       
   208   Exception EXPR is raised for invalid expressions and invalid arities.
       
   209 *)
       
   210 
       
   211 fun check (e as E (_, es)) = (forall check es andalso raw_check e) orelse raise TYPE e
       
   212 
       
   213 and raw_check (E (True, [])) = true
       
   214   | raw_check (E (False, [])) = true
       
   215   | raw_check (e as E (Not, [_])) = all_bool e
       
   216   | raw_check (e as E (And, _ :: _)) = all_bool e
       
   217   | raw_check (e as E (Or, _ :: _)) = all_bool e
       
   218   | raw_check (e as E (Imp, [_, _])) = all_bool e
       
   219   | raw_check (e as E (Iff, [_, _])) = all_bool e
       
   220   | raw_check (E (Ite, [e1, e2, e3])) =
       
   221       let val ty1 = type_of e1 and ty2 = type_of e2 and ty3 = type_of e3
       
   222       in eq_type (ty1, Bool) andalso eq_type (ty2, ty3) end
       
   223   | raw_check (E (Eq, [e1, e2])) =
       
   224       let val ty1 = type_of e1 and ty2 = type_of e2
       
   225       in eq_type (ty1, ty2) andalso not (eq_type (ty1, Bool)) end
       
   226   | raw_check (E (App, [e1, e2])) =
       
   227       eq_type (fst (dest_func_type e1 (type_of e1)), type_of e2)
       
   228   | raw_check (E (Con _, [])) = true
       
   229   | raw_check (E (Num _, [])) = true
       
   230   | raw_check (e as E (Le, [_, _])) = all_real e
       
   231   | raw_check (e as E (Lt, [_, _])) = all_real e
       
   232   | raw_check (e as E (Neg, [_])) = all_real e
       
   233   | raw_check (e as E (Add, _)) = all_real e
       
   234   | raw_check (e as E (Sub, [_, _])) = all_real e
       
   235   | raw_check (e as E (Mul, [_, _])) = all_real e
       
   236   | raw_check (e as E (Div, [_, _])) = all_real e
       
   237   | raw_check (e as E (Min, [_, _])) = all_real e
       
   238   | raw_check (e as E (Max, [_, _])) = all_real e
       
   239   | raw_check (e as E (Abs, [_])) = all_real e
       
   240   | raw_check e = raise EXPR e
       
   241 
       
   242 end
       
   243 
       
   244 structure Argo_Exprtab = Table(type key = Argo_Expr.expr val ord = Argo_Expr.expr_ord)