Theory IMP2_Var_Abs
section ‹Abstraction over Program Variables›
theory IMP2_Var_Abs
imports "../basic/Semantics" "../parser/Parser" IMP2_Basic_Simpset
begin
definition VAR :: "'v ⇒ ('v ⇒ 'a) ⇒ 'a"
where "VAR v f ≡ f v"
ML ‹ structure Program_Variables
= struct
datatype T = AbsInfo of ((IMP_Syntax.impvar * string) * term) list * (string * term)
val stateN = "𝔰"
val nameT = @{typ vname}
val avalueT = @{typ val}
val pvalueT = @{typ pval}
fun mk_vref_t state_t (ivname,IMP_Syntax.VAL) = state_t $ IMP_Syntax.mk_varname ivname $ @{term "0::int"}
| mk_vref_t state_t (ivname,IMP_Syntax.ARRAY) = state_t $ IMP_Syntax.mk_varname ivname
val stateT = nameT --> avalueT
fun abstract_var statev ((imp_var, sfx_name), v) t = let
val T = fastype_of t
val vT = fastype_of v
val t = Term.lambda_name (sfx_name,v) t
val vref_t = mk_vref_t statev imp_var
in
Const (@{const_name VAR}, vT --> (vT --> T) --> T) $ vref_t $ t
end
fun get_statev (AbsInfo (_,(_,v))) = v
fun gen_declare_variables imp_x_isa_names isa_suffix ctxt = let
val ctxt = ctxt |> Variable.set_body true
val isa_statename = suffix isa_suffix stateN
val (statev,ctxt) = yield_singleton Variable.add_fixes isa_statename ctxt
val statev = Free (statev,stateT)
val ctxt = Variable.declare_constraints statev ctxt
fun imp_var_isa_T (_,IMP_Syntax.VAL) = pvalueT
| imp_var_isa_T (_,IMP_Syntax.ARRAY) = avalueT
fun declare_impv (imp_var,isa_name) ctxt = let
val isa_name = suffix isa_suffix isa_name
val (vname,ctxt) = yield_singleton Variable.add_fixes isa_name ctxt
val v = Free (vname, imp_var_isa_T imp_var)
val ctxt = Variable.declare_constraints v ctxt
in
(((imp_var,isa_name),v), Proof_Context.augment v ctxt )
end
val (vs, ctxt) = fold_map declare_impv imp_x_isa_names ctxt
in
(AbsInfo (vs, (isa_statename, statev)), ctxt)
end
fun declare_variables imp_vars sfx ctxt = let
val imp_x_isa_names = imp_vars ~~ (map fst imp_vars)
in
gen_declare_variables imp_x_isa_names sfx ctxt
end
fun abstract_vars (AbsInfo (nsvs, (_,statev))) t = let
val frees = Term.add_frees t [] |> map Free |> Termtab.make_set
fun absv (nss,v) =
if Termtab.defined frees v then abstract_var statev (nss,v)
else I
val t = fold absv nsvs t
in
t
end
fun abstract_state (AbsInfo (_, (staten,statev))) t = Term.lambda_name (staten, statev) t
fun abstract vinfo = abstract_vars vinfo #> abstract_state vinfo
end
›
end