src/Tools/code/code_thingol.ML
changeset 31724 9b5a128cdb5c
parent 31156 90fed3d4430f
equal deleted inserted replaced
31723:f5cafe803b55 31724:9b5a128cdb5c
     6 *)
     6 *)
     7 
     7 
     8 infix 8 `%%;
     8 infix 8 `%%;
     9 infix 4 `$;
     9 infix 4 `$;
    10 infix 4 `$$;
    10 infix 4 `$$;
    11 infixr 3 `|->;
    11 infixr 3 `|=>;
    12 infixr 3 `|-->;
    12 infixr 3 `|==>;
    13 
    13 
    14 signature BASIC_CODE_THINGOL =
    14 signature BASIC_CODE_THINGOL =
    15 sig
    15 sig
    16   type vname = string;
    16   type vname = string;
    17   datatype dict =
    17   datatype dict =
    23   type const = string * ((itype list * dict list list) * itype list (*types of arguments*))
    23   type const = string * ((itype list * dict list list) * itype list (*types of arguments*))
    24   datatype iterm =
    24   datatype iterm =
    25       IConst of const
    25       IConst of const
    26     | IVar of vname
    26     | IVar of vname
    27     | `$ of iterm * iterm
    27     | `$ of iterm * iterm
    28     | `|-> of (vname * itype) * iterm
    28     | `|=> of (vname * itype) * iterm
    29     | ICase of ((iterm * itype) * (iterm * iterm) list) * iterm;
    29     | ICase of ((iterm * itype) * (iterm * iterm) list) * iterm;
    30         (*((term, type), [(selector pattern, body term )]), primitive term)*)
    30         (*((term, type), [(selector pattern, body term )]), primitive term)*)
    31   val `$$ : iterm * iterm list -> iterm;
    31   val `$$ : iterm * iterm list -> iterm;
    32   val `|--> : (vname * itype) list * iterm -> iterm;
    32   val `|==> : (vname * itype) list * iterm -> iterm;
    33   type typscheme = (vname * sort) list * itype;
    33   type typscheme = (vname * sort) list * itype;
    34 end;
    34 end;
    35 
    35 
    36 signature CODE_THINGOL =
    36 signature CODE_THINGOL =
    37 sig
    37 sig
   126 
   126 
   127 datatype iterm =
   127 datatype iterm =
   128     IConst of const
   128     IConst of const
   129   | IVar of vname
   129   | IVar of vname
   130   | `$ of iterm * iterm
   130   | `$ of iterm * iterm
   131   | `|-> of (vname * itype) * iterm
   131   | `|=> of (vname * itype) * iterm
   132   | ICase of ((iterm * itype) * (iterm * iterm) list) * iterm;
   132   | ICase of ((iterm * itype) * (iterm * iterm) list) * iterm;
   133     (*see also signature*)
   133     (*see also signature*)
   134 
   134 
   135 val op `$$ = Library.foldl (op `$);
   135 val op `$$ = Library.foldl (op `$);
   136 val op `|--> = Library.foldr (op `|->);
   136 val op `|==> = Library.foldr (op `|=>);
   137 
   137 
   138 val unfold_app = unfoldl
   138 val unfold_app = unfoldl
   139   (fn op `$ t => SOME t
   139   (fn op `$ t => SOME t
   140     | _ => NONE);
   140     | _ => NONE);
   141 
   141 
   142 val split_abs =
   142 val split_abs =
   143   (fn (v, ty) `|-> (t as ICase (((IVar w, _), [(p, t')]), _)) =>
   143   (fn (v, ty) `|=> (t as ICase (((IVar w, _), [(p, t')]), _)) =>
   144         if v = w then SOME (((v, SOME p), ty), t') else SOME (((v, NONE), ty), t)
   144         if v = w then SOME (((v, SOME p), ty), t') else SOME (((v, NONE), ty), t)
   145     | (v, ty) `|-> t => SOME (((v, NONE), ty), t)
   145     | (v, ty) `|=> t => SOME (((v, NONE), ty), t)
   146     | _ => NONE);
   146     | _ => NONE);
   147 
   147 
   148 val unfold_abs = unfoldr split_abs;
   148 val unfold_abs = unfoldr split_abs;
   149 
   149 
   150 val split_let = 
   150 val split_let = 
   159    | _ => NONE;
   159    | _ => NONE;
   160 
   160 
   161 fun fold_aiterms f (t as IConst _) = f t
   161 fun fold_aiterms f (t as IConst _) = f t
   162   | fold_aiterms f (t as IVar _) = f t
   162   | fold_aiterms f (t as IVar _) = f t
   163   | fold_aiterms f (t1 `$ t2) = fold_aiterms f t1 #> fold_aiterms f t2
   163   | fold_aiterms f (t1 `$ t2) = fold_aiterms f t1 #> fold_aiterms f t2
   164   | fold_aiterms f (t as _ `|-> t') = f t #> fold_aiterms f t'
   164   | fold_aiterms f (t as _ `|=> t') = f t #> fold_aiterms f t'
   165   | fold_aiterms f (ICase (_, t)) = fold_aiterms f t;
   165   | fold_aiterms f (ICase (_, t)) = fold_aiterms f t;
   166 
   166 
   167 fun fold_constnames f =
   167 fun fold_constnames f =
   168   let
   168   let
   169     fun add (IConst (c, _)) = f c
   169     fun add (IConst (c, _)) = f c
   171   in fold_aiterms add end;
   171   in fold_aiterms add end;
   172 
   172 
   173 fun fold_varnames f =
   173 fun fold_varnames f =
   174   let
   174   let
   175     fun add (IVar v) = f v
   175     fun add (IVar v) = f v
   176       | add ((v, _) `|-> _) = f v
   176       | add ((v, _) `|=> _) = f v
   177       | add _ = I;
   177       | add _ = I;
   178   in fold_aiterms add end;
   178   in fold_aiterms add end;
   179 
   179 
   180 fun fold_unbound_varnames f =
   180 fun fold_unbound_varnames f =
   181   let
   181   let
   182     fun add _ (IConst _) = I
   182     fun add _ (IConst _) = I
   183       | add vs (IVar v) = if not (member (op =) vs v) then f v else I
   183       | add vs (IVar v) = if not (member (op =) vs v) then f v else I
   184       | add vs (t1 `$ t2) = add vs t1 #> add vs t2
   184       | add vs (t1 `$ t2) = add vs t1 #> add vs t2
   185       | add vs ((v, _) `|-> t) = add (insert (op =) v vs) t
   185       | add vs ((v, _) `|=> t) = add (insert (op =) v vs) t
   186       | add vs (ICase (_, t)) = add vs t;
   186       | add vs (ICase (_, t)) = add vs t;
   187   in add [] end;
   187   in add [] end;
   188 
   188 
   189 fun collapse_let (((v, ty), se), be as ICase (((IVar w, _), ds), _)) =
   189 fun collapse_let (((v, ty), se), be as ICase (((IVar w, _), ds), _)) =
   190       let
   190       let
   202   let
   202   let
   203     val j = length ts;
   203     val j = length ts;
   204     val l = k - j;
   204     val l = k - j;
   205     val ctxt = (fold o fold_varnames) Name.declare ts Name.context;
   205     val ctxt = (fold o fold_varnames) Name.declare ts Name.context;
   206     val vs_tys = Name.names ctxt "a" ((curry Library.take l o curry Library.drop j) tys);
   206     val vs_tys = Name.names ctxt "a" ((curry Library.take l o curry Library.drop j) tys);
   207   in vs_tys `|--> IConst c `$$ ts @ map (fn (v, _) => IVar v) vs_tys end;
   207   in vs_tys `|==> IConst c `$$ ts @ map (fn (v, _) => IVar v) vs_tys end;
   208 
   208 
   209 fun contains_dictvar t =
   209 fun contains_dictvar t =
   210   let
   210   let
   211     fun contains (DictConst (_, dss)) = (fold o fold) contains dss
   211     fun contains (DictConst (_, dss)) = (fold o fold) contains dss
   212       | contains (DictVar _) = K true;
   212       | contains (DictVar _) = K true;
   216   end;
   216   end;
   217   
   217   
   218 fun locally_monomorphic (IConst _) = false
   218 fun locally_monomorphic (IConst _) = false
   219   | locally_monomorphic (IVar _) = true
   219   | locally_monomorphic (IVar _) = true
   220   | locally_monomorphic (t `$ _) = locally_monomorphic t
   220   | locally_monomorphic (t `$ _) = locally_monomorphic t
   221   | locally_monomorphic (_ `|-> t) = locally_monomorphic t
   221   | locally_monomorphic (_ `|=> t) = locally_monomorphic t
   222   | locally_monomorphic (ICase ((_, ds), _)) = exists (locally_monomorphic o snd) ds;
   222   | locally_monomorphic (ICase ((_, ds), _)) = exists (locally_monomorphic o snd) ds;
   223 
   223 
   224 
   224 
   225 (** namings **)
   225 (** namings **)
   226 
   226 
   395 
   395 
   396 fun map_terms_bottom_up f (t as IConst _) = f t
   396 fun map_terms_bottom_up f (t as IConst _) = f t
   397   | map_terms_bottom_up f (t as IVar _) = f t
   397   | map_terms_bottom_up f (t as IVar _) = f t
   398   | map_terms_bottom_up f (t1 `$ t2) = f
   398   | map_terms_bottom_up f (t1 `$ t2) = f
   399       (map_terms_bottom_up f t1 `$ map_terms_bottom_up f t2)
   399       (map_terms_bottom_up f t1 `$ map_terms_bottom_up f t2)
   400   | map_terms_bottom_up f ((v, ty) `|-> t) = f
   400   | map_terms_bottom_up f ((v, ty) `|=> t) = f
   401       ((v, ty) `|-> map_terms_bottom_up f t)
   401       ((v, ty) `|=> map_terms_bottom_up f t)
   402   | map_terms_bottom_up f (ICase (((t, ty), ps), t0)) = f
   402   | map_terms_bottom_up f (ICase (((t, ty), ps), t0)) = f
   403       (ICase (((map_terms_bottom_up f t, ty), (map o pairself)
   403       (ICase (((map_terms_bottom_up f t, ty), (map o pairself)
   404         (map_terms_bottom_up f) ps), map_terms_bottom_up f t0));
   404         (map_terms_bottom_up f) ps), map_terms_bottom_up f t0));
   405 
   405 
   406 fun map_terms_stmt f NoStmt = NoStmt
   406 fun map_terms_stmt f NoStmt = NoStmt
   579       let
   579       let
   580         val (v, t) = Syntax.variant_abs abs;
   580         val (v, t) = Syntax.variant_abs abs;
   581       in
   581       in
   582         translate_typ thy algbr funcgr ty
   582         translate_typ thy algbr funcgr ty
   583         ##>> translate_term thy algbr funcgr thm t
   583         ##>> translate_term thy algbr funcgr thm t
   584         #>> (fn (ty, t) => (v, ty) `|-> t)
   584         #>> (fn (ty, t) => (v, ty) `|=> t)
   585       end
   585       end
   586   | translate_term thy algbr funcgr thm (t as _ $ _) =
   586   | translate_term thy algbr funcgr thm (t as _ $ _) =
   587       case strip_comb t
   587       case strip_comb t
   588        of (Const (c, ty), ts) =>
   588        of (Const (c, ty), ts) =>
   589             translate_app thy algbr funcgr thm ((c, ty), ts)
   589             translate_app thy algbr funcgr thm ((c, ty), ts)
   634         Term.strip_abs_eta 1 (the_single ts_clause)
   634         Term.strip_abs_eta 1 (the_single ts_clause)
   635       in [(true, (Free v_ty, body))] end
   635       in [(true, (Free v_ty, body))] end
   636       else map (uncurry mk_clause)
   636       else map (uncurry mk_clause)
   637         (AList.make (Code.no_args thy) case_pats ~~ ts_clause);
   637         (AList.make (Code.no_args thy) case_pats ~~ ts_clause);
   638     fun retermify ty (_, (IVar x, body)) =
   638     fun retermify ty (_, (IVar x, body)) =
   639           (x, ty) `|-> body
   639           (x, ty) `|=> body
   640       | retermify _ (_, (pat, body)) =
   640       | retermify _ (_, (pat, body)) =
   641           let
   641           let
   642             val (IConst (_, (_, tys)), ts) = unfold_app pat;
   642             val (IConst (_, (_, tys)), ts) = unfold_app pat;
   643             val vs = map2 (fn IVar x => fn ty => (x, ty)) ts tys;
   643             val vs = map2 (fn IVar x => fn ty => (x, ty)) ts tys;
   644           in vs `|--> body end;
   644           in vs `|==> body end;
   645     fun mk_icase const t ty clauses =
   645     fun mk_icase const t ty clauses =
   646       let
   646       let
   647         val (ts1, ts2) = chop t_pos (map (retermify ty) clauses);
   647         val (ts1, ts2) = chop t_pos (map (retermify ty) clauses);
   648       in
   648       in
   649         ICase (((t, ty), map_filter (fn (b, d) => if b then SOME d else NONE) clauses),
   649         ICase (((t, ty), map_filter (fn (b, d) => if b then SOME d else NONE) clauses),
   666       val ctxt = (fold o fold_aterms) Term.declare_term_frees ts Name.context;
   666       val ctxt = (fold o fold_aterms) Term.declare_term_frees ts Name.context;
   667       val vs = Name.names ctxt "a" tys;
   667       val vs = Name.names ctxt "a" tys;
   668     in
   668     in
   669       fold_map (translate_typ thy algbr funcgr) tys
   669       fold_map (translate_typ thy algbr funcgr) tys
   670       ##>> translate_case thy algbr funcgr thm case_scheme ((c, ty), ts @ map Free vs)
   670       ##>> translate_case thy algbr funcgr thm case_scheme ((c, ty), ts @ map Free vs)
   671       #>> (fn (tys, t) => map2 (fn (v, _) => pair v) vs tys `|--> t)
   671       #>> (fn (tys, t) => map2 (fn (v, _) => pair v) vs tys `|==> t)
   672     end
   672     end
   673   else if length ts > num_args then
   673   else if length ts > num_args then
   674     translate_case thy algbr funcgr thm case_scheme ((c, ty), Library.take (num_args, ts))
   674     translate_case thy algbr funcgr thm case_scheme ((c, ty), Library.take (num_args, ts))
   675     ##>> fold_map (translate_term thy algbr funcgr thm) (Library.drop (num_args, ts))
   675     ##>> fold_map (translate_term thy algbr funcgr thm) (Library.drop (num_args, ts))
   676     #>> (fn (t, ts) => t `$$ ts)
   676     #>> (fn (t, ts) => t `$$ ts)