src/Pure/sign.ML
changeset 4961 27f559b54c57
parent 4951 8637b29e6c38
child 4998 28fe46a570d7
equal deleted inserted replaced
4960:e07823c1ebff 4961:27f559b54c57
   526 
   526 
   527 
   527 
   528 
   528 
   529 (** certify types and terms **)   (*exception TYPE*)
   529 (** certify types and terms **)   (*exception TYPE*)
   530 
   530 
       
   531 (* certify_typ *)
       
   532 
   531 val certify_typ = Type.cert_typ o tsig_of;
   533 val certify_typ = Type.cert_typ o tsig_of;
       
   534 
       
   535 
       
   536 (* certify_term *)
   532 
   537 
   533 (*check for duplicate TVars with distinct sorts*)
   538 (*check for duplicate TVars with distinct sorts*)
   534 fun nodup_TVars (tvars, T) =
   539 fun nodup_TVars (tvars, T) =
   535   (case T of
   540   (case T of
   536     Type (_, Ts) => nodup_TVars_list (tvars, Ts)
   541     Type (_, Ts) => nodup_TVars_list (tvars, Ts)
   567           let val (vars',tvars') = nodups vars tvars s in
   572           let val (vars',tvars') = nodups vars tvars s in
   568             nodups vars' tvars' t
   573             nodups vars' tvars' t
   569           end);
   574           end);
   570   in nodups [] [] tm; () end;
   575   in nodups [] [] tm; () end;
   571 
   576 
   572 
   577 (*compute and check type of the term*)
   573 fun mapfilt_atoms f (Abs (_, _, t)) = mapfilt_atoms f t
   578 fun type_check sg tm =
   574   | mapfilt_atoms f (t $ u) = mapfilt_atoms f t @ mapfilt_atoms f u
   579   let
   575   | mapfilt_atoms f a = (case f a of Some y => [y] | None => []);
   580     val prt =
       
   581       setmp Syntax.show_brackets true
       
   582         (setmp long_names true (pretty_term sg));
       
   583     val prT = setmp long_names true (pretty_typ sg);
       
   584 
       
   585     fun err_appl why bs t T u U =
       
   586       let
       
   587         val xs = map Free bs;		(*we do not rename here*)
       
   588         val t' = subst_bounds (xs, t);
       
   589         val u' = subst_bounds (xs, u);
       
   590         val text = cat_lines
       
   591          ["Type error in application: " ^ why,
       
   592           "",
       
   593           Pretty.string_of (Pretty.block [Pretty.str "Operator:", Pretty.brk 2, prt t',
       
   594             Pretty.str " :: ", prT T]),
       
   595           Pretty.string_of (Pretty.block [Pretty.str "Operand:", Pretty.brk 3, prt u',
       
   596             Pretty.str " :: ", prT U]), ""];
       
   597       in raise TYPE (text, [T, U], [t', u']) end;
       
   598 
       
   599     fun typ_of (_, Const (_, T)) = T
       
   600       | typ_of (_, Free  (_, T)) = T
       
   601       | typ_of (_, Var (_, T)) = T
       
   602       | typ_of (bs, Bound i) = snd (nth_elem (i, bs) handle LIST _ =>
       
   603           raise TYPE ("Loose bound variable: B." ^ string_of_int i, [], [Bound i]))
       
   604       | typ_of (bs, Abs (x, T, body)) = T --> typ_of ((x, T) :: bs, body)
       
   605       | typ_of (bs, t $ u) =
       
   606           let val T = typ_of (bs, t) and U = typ_of (bs, u) in
       
   607             (case T of
       
   608               Type ("fun", [T1, T2]) =>
       
   609                 if T1 = U then T2 else err_appl "Incompatible operand type." bs t T u U
       
   610             | _ => err_appl "Operator not of function type." bs t T u U)
       
   611           end;
       
   612 
       
   613   in typ_of ([], tm) end;
   576 
   614 
   577 
   615 
   578 fun certify_term sg tm =
   616 fun certify_term sg tm =
   579   let
   617   let
   580     val _ = check_stale sg;
   618     val _ = check_stale sg;
   581     val tsig = tsig_of sg;
   619     val tsig = tsig_of sg;
   582 
   620 
   583     fun show_const a T = quote a ^ " :: " ^ quote (string_of_typ sg T);
   621     fun show_const a T = quote a ^ " :: " ^ quote (string_of_typ sg T);
   584 
   622 
   585     fun atom_err (Const (a, T)) =
   623     fun atom_err (errs, Const (a, T)) =
   586         (case const_type sg a of
   624         (case const_type sg a of
   587           None => Some ("Undeclared constant " ^ show_const a T)
   625           None => ("Undeclared constant " ^ show_const a T) :: errs
   588         | Some U =>
   626         | Some U =>
   589             if Type.typ_instance (tsig, T, U) then None
   627             if Type.typ_instance (tsig, T, U) then errs
   590             else Some ("Illegal type for constant " ^ show_const a T))
   628             else ("Illegal type for constant " ^ show_const a T) :: errs)
   591       | atom_err (Var ((x, i), _)) =
   629       | atom_err (errs, Var ((x, i), _)) =
   592           if i < 0 then Some ("Negative index for Var " ^ quote x) else None
   630           if i < 0 then ("Negative index for Var " ^ quote x) :: errs else errs
   593       | atom_err _ = None;
   631       | atom_err (errs, _) = errs;
   594 
   632 
   595     val norm_tm =
   633     val norm_tm =
   596       (case it_term_types (Type.typ_errors tsig) (tm, []) of
   634       (case it_term_types (Type.typ_errors tsig) (tm, []) of
   597         [] => map_term_types (Type.norm_typ tsig) tm
   635         [] => map_term_types (Type.norm_typ tsig) tm
   598       | errs => raise TYPE (cat_lines errs, [], [tm]));
   636       | errs => raise TYPE (cat_lines errs, [], [tm]));
   599     val _ = nodup_Vars norm_tm;
   637     val _ = nodup_Vars norm_tm;
   600   in
   638   in
   601     (case mapfilt_atoms atom_err norm_tm of
   639     (case foldl_aterms atom_err ([], norm_tm) of
   602       [] => (norm_tm, type_of norm_tm, maxidx_of_term norm_tm)
   640       [] => (norm_tm, type_check sg norm_tm, maxidx_of_term norm_tm)
   603     | errs => raise TYPE (cat_lines errs, [], [norm_tm]))
   641     | errs => raise TYPE (cat_lines errs, [], [norm_tm]))
   604   end;
   642   end;
   605 
   643 
   606 
   644 
   607 
   645