Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Isabelle/Archive-of-Formal-Proofs/thys/MiniML/   (Sammlung formaler Beweise Version 2026-5©)  Datei vom 29.4.2026 mit Größe 15 kB image not shown  

Quelle  W.thy

  Sprache: Isabelle
 

(* Title:     MiniML/W.thy
   Author:    Dieter Nazareth, Wolfgang Naraschewski and Tobias Nipkow
   Copyright  1996 TU Muenchen
   2024: Conversion to Isar by LCP
*)


section "Correctness and completeness of type inference algorithm W"

theory W
  imports MiniML
begin

type_synonym result_W = "(subst * typ * nat) option"

― type inference algorithm W
fun W :: "[expr, ctxt, nat] => result_W" where
  "W (Var i) A n =
     (if i < length A then Some( id_subst,
                                 bound_typ_inst (λb. TVar(b+n)) (A!i),
                                 n + (min_new_bound_tv (A!i)) )
                      else None)"

"W (Abs e) A n = ( (S,t,m) := W e ((FVar n)#A) (Suc n);
                     Some( S, (S n) -> t, m) )"

"W (App e1 e2) A n = ( (S1,t1,m1) := W e1 A n;
                         (S2,t2,m2) := W e2 ($S1 A) m1;
                         U := mgu ($S2 t1) (t2 -> (TVar m2));
                         Some( $U $S2 S1, U m2, Suc m2) )"

"W (LET e1 e2) A n = ( (S1,t1,m1) := W e1 A n;
                         (S2,t2,m2) := W e2 ((gen ($S1 A) t1)#($S1 A)) m1;
                         Some( $S2 S1, t2, m2) )"


declare Suc_le_lessD [simp]

inductive_simps has_type_simps:
  "A Var n :: t"
  "A Abs e :: t"
  "A App e1 e2 ::t"
  "A LET e1 e2 ::t"


― the resulting type variable is always greater or equal than the given one
lemma W_var_ge: 
  "W e A n = Some (S,t,m) ==> n m"
proof (induction e arbitrary: A n S t m)
  case Var thus ?case by (auto split: if_splits)
next
  case Abs thus ?case by (fastforce split: split_option_bind_asm)
next
  case App thus ?case by (fastforce split: split_option_bind_asm)
next
  case LET thus ?case by (fastforce split: split_option_bind_asm)
qed

declare W_var_ge [simp] (* FIXME*)

lemma W_var_geD: 
  "Some (S,t,m) = W e A n ==> nm"
  by (metis W_var_ge)


lemma new_tv_compatible_W: 
  "new_tv n A ==> Some (S,t,m) = W e A n ==> new_tv m A"
  by (metis W_var_ge new_tv_le)

lemma new_tv_bound_typ_inst_sch: 
  "new_tv n sch ==> new_tv (n + (min_new_bound_tv sch)) (bound_typ_inst (λb. TVar (b + n)) sch)"
proof (induction sch)
  case FVar thus ?case by simp
next
  case BVar thus ?case by simp
next
  case SFun thus ?case by(auto simp add: max_def nle_le dest: new_tv_le add_left_mono)
qed

― resulting type variable is new
lemma new_tv_W [rule_format]: 
  "n A S t m. new_tv n A W e A n = Some (S,t,m)
               new_tv m S new_tv m t"
proof (induction e)
  case Var thus ?case
    by (auto simp add: new_tv_bound_typ_inst_sch dest: new_tv_nth_nat_A)
next
  case Abs thus ?case
    apply (simp add: new_tv_subst split: split_option_bind)
    by (metis lessI new_tv_Cons new_tv_FVar new_tv_Suc new_tv_compatible_W )
next
  case App thus ?case
    apply (simp split: split_option_bind)
    by (smt (verit, ccfv_threshold) W_var_geD fun.map_comp lessI mgu_new new_tv_Fun new_tv_Suc new_tv_le new_tv_subst new_tv_subst_comp_1 new_tv_subst_scheme_list new_tv_subst_te)
next
  case LET thus ?case
    apply (simp split: split_option_bind)
    by (metis W_var_ge new_tv_Cons new_tv_compatible_gen new_tv_le new_tv_subst_comp_1 new_tv_subst_scheme_list)
qed

lemma free_tv_bound_typ_inst1:
  "v free_tv sch ==> v free_tv (bound_typ_inst (TVar S) sch) ==> x. v = S x"
  by (induction sch) auto

lemma free_tv_W: 
  "W e A n = Some (S,t,m) ==>
          (vfree_tv S vfree_tv t) ==> v<n ==> vfree_tv A"
proof (induction e arbitrary: n A S t m v)
  case (Var i) 
  show ?case
  proof (cases "v free_tv (A!i)")
    case True
    with Var show ?thesis 
      by (metis W.simps(1) free_tv_nth_A_impl_free_tv_A not_None_eq)
  next
    case False
    with Var show ?thesis
      by (force simp: o_def free_tv_nth_A_impl_free_tv_A dest: free_tv_bound_typ_inst1 
          split: if_split_asm)
  qed
next
  case (Abs e n A S t m v) 
  then obtain S1 t1 n1 where "W e (FVar n # A) (Suc n) = Some (S1, t1, n1)"
    by (metis (lifting) W.simps(2) not_None_eq option_bind_eq_None prod_cases3)
  then show ?case
    using Abs.IH [of "FVar n # A" "Suc n" S1 t1 n1 v] Abs.prems 
    by (force simp: codD cod_app_subst)
next
  case (App e1 e2 n A S t m v) 
  then show ?case
  proof (clarsimp split: split_option_bind_asm prod.split_asm)
    fix S' t' n1 S1 t1 n2 S2
    assume v: "v free_tv ($ S2 $ S1 S') v free_tv (S2 n2)"
      and "v < n"
      and e1: "W e1 A n = Some (S', t', n1)"
      and e2: "W e2 ($ S' A) n1 = Some (S1, t1, n2)"
      and mgu: "mgu ($ S1 t') (t1 -> TVar n2) = Some S2"
    have n: "n n1" "n1 n2"
      using e1 e2 by auto
    show "v free_tv A"
      using v
    proof
      assume v1: "v free_tv ($ S2 $ S1 S')"
      then have "v free_tv S2 free_tv (λx. $ S1 (S' x))"
        by (metis (no_types, lifting) ext comp_apply free_tv_o_subst fun.map_comp
            subsetD)
      moreover
      have "free_tv S2 insert n2 (free_tv ($ S1 t') free_tv t1)"
        using mgu mgu_free by fastforce
      ultimately
      show "v free_tv A"
        using App.IH n v1 v<n\ e1 e2 codD free_tv_app_subst_scheme_list 
        by (smt (verit, ccfv_threshold) Un_iff free_tv_app_subst_te free_tv_o_subst
            fun.map_comp insert_iff linorder_not_less order.strict_trans2 subsetD)
    next
      assume v2: "v free_tv (S2 n2)"
      then have "v < n1"
        using App.prems n by linarith
      then have "free_tv S2 free_tv ($ S1 t') free_tv (t1 -> TVar n2)"
        using mgu mgu_free by blast
      then show "v free_tv A"
        using App.IH n v2 v<n\ v<n1\ e1 e2 codD free_tv_app_subst_scheme_list 
        by (smt (verit, ccfv_threshold) UnE  cod_app_subst empty_iff 
            free_tv_app_subst_te free_tv_typ.simps insert_iff linorder_not_less subsetD)
    qed
  qed
next
  case (LET e1 e2 n A S t2 n3 v) 
  then show ?case
  proof (clarsimp split: split_option_bind_asm prod.split_asm)
    fix S1 t1 n2 S2
    assume "v free_tv ($ S2 S1) v free_tv t2"
      and "v < n"
      and "W e1 A n = Some (S1, t1, n2)"
      and "W e2 (gen ($ S1 A) t1 # $ S1 A) n2 = Some (S2, t2, n3)"
    with LET.IH
    show "v free_tv A"
      by (smt (verit) Un_iff W_var_geD codD free_tv_app_subst_scheme_list 
          free_tv_gen_cons free_tv_o_subst order.strict_trans2 subsetD)
  qed
qed

lemma weaken_A_Int_B_eq_empty: "(x. x A x B) ==> A B = {}"
  by blast

lemma weaken_not_elem_A_minus_B: "x A x B ==> x A - B"
  by blast

― correctness of W with respect to @{text has_type}
lemma W_correct_lemma: "[new_tv n A; Some (S,t,m) = W e A n] ==> $S A e :: t"
proof (induction "e" arbitrary: A S t m n)
  case Var thus ?case
    using is_bound_typ_instance by (auto split: if_splits)
next
  case (Abs e) thus ?case
    apply (simp split: split_option_bind_asm prod.splits)
    by (metis AbsI app_subst_Cons app_subst_type_scheme.simps(1) lessI new_tv_Cons
        new_tv_FVar new_tv_Suc)
next
  case (App e1 e2) 
  then show ?case
  proof (simp split: split_option_bind_asm prod.splits)
    fix S1 t1 n1 S2 t2 n2 S3
    assume e1: "W e1 A n = Some (S1, t1, n1)"
      and e2: "W e2 ($ S1 A) n1 = Some (S2, t2, n2)"
      and mgu: "mgu ($ S2 t1) (t2 -> TVar n2) = Some S3"
    show "$ (λa. $ S3 ($ S2 (S1 a))) A App e1 e2 :: S3 n2"
    proof (rule has_type.AppI)
      have "$ S3 (t2 -> TVar n2) = $ S3 ($ S2 t1)"
        using mgu mgu_eq by presburger
      with App show "$ (λa. $ S3 ($ S2 (S1 a))) A e1 :: $ S3 t2 -> S3 n2"
        by (metis (no_types) Type.app_subst_Fun Type.app_subst_TVar e1 has_type_cl_sub subst_comp_scheme_list)
      show "$ (λa. $ S3 ($ S2 (S1 a))) A e2 :: $ S3 t2"
        using e1 e2 mgu App
        by (metis has_type_cl_sub new_tv_W new_tv_compatible_W new_tv_subst_scheme_list
            subst_comp_scheme_list)
    qed
  qed
next
  case (LET e1 e2) thus ?case
  proof (simp split: split_option_bind_asm prod.splits)
    fix S1 t1 m1 S2
    assume "new_tv n A"
      and e1: "W e1 A n = Some (S1, t1, m1)"
      and e2: "W e2 (gen ($ S1 A) t1 # $ S1 A) m1 = Some (S2, t, m)"
    show "$ (λa. $ S2 (S1 a)) A LET e1 e2 :: t"
    proof (rule has_type.LETI)
      show "$ (λa. $ S2 (S1 a)) A e1 :: $ S2 t1"
        using LET e1 by (metis (no_types, lifting) has_type_cl_sub subst_comp_scheme_list)
      have "free_tv S2 (free_tv t1 - free_tv ($ S1 A)) = {}"
        using e1 e2 LET
        by (smt (verit) DiffD2 Diff_subset free_tv_W free_tv_gen_cons
            free_tv_le_new_tv new_tv_W subsetD weaken_A_Int_B_eq_empty)
      then
      show "gen ($ (λa. $ S2 (S1 a)) A) ($ S2 t1) # $ (λa. $ S2 (S1 a)) A e2 :: t"
        using e1 e2 LET
        by (metis app_subst_Cons gen_subst_commutes new_tv_Cons new_tv_W new_tv_compatible_W
            new_tv_compatible_gen new_tv_subst_scheme_list subst_comp_scheme_list)
    qed
  qed
qed

― Completeness of W w.r.t. @{text has_type}
lemma W_complete_lemma: 
  "[$S' A e :: t'; new_tv n A] ==>
   S t. (m. W e A n = Some (S,t,m)) (R. $S' A = $R ($S A) t' = $R t)"
proof (induction e arbitrary: S' A t' n)
  case (Var u) thus ?case
  proof (clarsimp simp add: has_type_simps is_bound_typ_instance)
    fix S :: "nat ==> typ"
    assume A: "new_tv n A" "u < length A"
    show "R. $ S' A = $ R A
      bound_typ_inst S ($ S' A ! u) = $ R (bound_typ_inst (λb. TVar (b + n)) (A ! u))"
    proof (intro exI conjI)
      show "$ S' A = $ (λx. if x < n then S' x else S (x - n)) A"
        using Var.prems(2) new_if_subst_type_scheme_list by force
      show "bound_typ_inst S ($ S' A ! u) = $ (λx. if x < n then S' x else S (x - n)) (bound_typ_inst (λb. TVar (b + n)) (A ! u))"
        using A 
        by (simp add: new_if_subst_type_scheme  new_tv_nth_nat_A o_def nth_subst
                 flip: bound_typ_inst_composed_subst)
    qed
  qed
next
  case (Abs e S' A t' n) 
  then obtain t1 t2 where "t' = t1 -> t2" "mk_scheme t1 # $ S' A e :: t2"
    by (auto simp: has_type_simps)
  with Abs.prems Abs.IH[of "λx. if x=n then t1 else (S' x)" "(FVar n) #A" t2 "Suc n"]
  show ?case
    by (force dest!: mk_scheme_injective)
next
  case (App e1 e2) 
  then obtain t2 where e2t: "$ S' A e2 :: t2"  and e1t: "$ S' A e1 :: t2 -> t'"
    by (auto simp: has_type_simps)
  then obtain S t m R 
    where e1: "W e1 A n = Some (S, t, m)" and R: "$ S' A = $ R ($ S A)" "t2 -> t' = $ R t"
    using App by blast
  with App.prems have new_tv_m: "new_tv m ($ S A)"
    by (metis new_tv_W new_tv_compatible_W new_tv_subst_scheme_list)
  with App R
  obtain Sa ta ma Ra where We2: "W e2 ($ S A) m = Some (Sa, ta, ma)"
           and RSA: "$ R ($ S A) = $ Ra ($ Sa ($ S A))" 
           and t2eq: "t2 = $ Ra ta"
    by (metis e2t)
  define F where "F (λx. if x = ma then t'
                            else if x free_tv t - free_tv Sa then R x
                            else Ra x)"
  have "ma free_tv t"
    by (metis App.prems(2) W_var_geD We2 e1 new_tv_W new_tv_le
        new_tv_not_free_tv)
  have "$ F (Sa na) = R na" if "na free_tv t" for na
  proof -
    have "na ma"
      using ma free_tv t that by auto
    show ?thesis
    proof (cases "na free_tv Sa")
      case True
      then have "R na = $ Ra (Sa na)"
        by (metis (lifting) App.prems(2) RSA We2 e1 eq_subst_scheme_list_eq_free free_tv_W
            free_tv_le_new_tv new_tv_W subst_comp_scheme_list that)
      then show ?thesis
        by (metis F_def True We2 new_tv_m codD cod_app_subst eq_free_eq_subst_te
            new_tv_W new_tv_not_free_tv weaken_not_elem_A_minus_B)
    next
      case False
      then show ?thesis
        using not_free_impl_id [OF False] na ma that
        by (simp add: F_def)
    qed
  qed
  then have *: "$ F ($ Sa t) = $ Ra ta -> t'"
    using eq_free_eq_subst_te subst_comp_te using R t2eq by fastforce
  moreover have "Ra na = F na"
    if "na free_tv ta" for na
  proof -
    have "na ma"
      using We2 new_tv_W new_tv_m new_tv_not_free_tv that by blast
    show ?thesis
    proof (cases "na free_tv t - free_tv Sa")
      case True
      then have "$ R ($ S A) = $ (λx. $ Ra (Sa x)) ($ S A)"
        by (metis RSA subst_comp_scheme_list)
      then have "Ra na = R na"
        by (metis that App.prems(2) DiffE True Type.app_subst_TVar We2 free_tv_W e1 
            eq_subst_scheme_list_eq_free free_tv_le_new_tv new_tv_W not_free_impl_id)
      with na ma True show ?thesis
        by (simp add: F_def)
    next
      case False
      then show ?thesis
        using F_def na ma by presburger
    qed
  qed
  ultimately have "$ F ($ Sa t) = $ F (ta -> (TVar ma))"
    by (metis eq_free_eq_subst_te F_def Type.app_subst_Fun Type.app_subst_TVar)
  with mgu_Some obtain Sx Rb where Sx: "mgu ($ Sa t) (ta -> TVar ma) = Some Sx" 
    and Rb: "F = $ Rb Sx"
    using mgu_mg by blast
  have t': "t' = $ Rb (Sx ma)"
    by (metis F_def Rb comp_def)
  have "$ Ra ($ Sa ($ S A)) = $ (λx. $ Rb (Sx x)) ($ Sa ($ S A))"
  proof (intro eq_free_eq_subst_scheme_list)
    fix na :: nat
    assume na: "na free_tv ($ Sa ($ S A))"
    then have "ma na"
      by (metis We2 new_tv_W new_tv_compatible_W new_tv_m new_tv_not_free_tv
          new_tv_subst_scheme_list)
    show "Ra na = $ Rb (Sx na)"
    proof (cases "na free_tv t - free_tv Sa")
      case True
      then have "na cod Sa free_tv ($ S A)"
        using free_tv_app_subst_scheme_list na by blast
      with ma na Rb show ?thesis
        by (smt (verit, ccfv_SIG) DiffD2 F_def RSA Rb Type.app_subst_TVar Un_iff codD
            comp_apply eq_subst_scheme_list_eq_free not_free_impl_id subst_comp_scheme_list)
    next
      case False
      then show ?thesis
        by (metis F_def Rb ma na comp_apply)
    qed
  qed
  then have "$ S' A = $ Rb ($ ($ Sx $ Sa S) A)"
    by (metis (no_types, lifting) ext R(1) RSA comp_apply fun.map_comp
        subst_comp_scheme_list)
  with We2 Sx show ?case
    by (auto simp add: e1 t')
next
  case (LET e1 e2) 
  then obtain t1 where t1: "$ S' A e1 :: t1" "gen ($ S' A) t1 # $ S' A e2 :: t'"
    by (auto simp: has_type_simps)
  then obtain S t m R where e1: "W e1 A n = Some (S, t, m)" "$ S' A = $ R ($ S A)"
      and "gen ($ R ($ S A)) ($ R t) # $ R ($ S A) e2 :: t'"
    using LET by metis
  then have "$ R (gen ($ S A) t) # $ R ($ S A) e2 :: t'"
    using gen_bound_typ_instance has_type_le_env le_env_Cons le_env_refl
    by presburger
  moreover
  have "new_tv m (gen ($ S A) t) new_tv m ($ S A)"
    using LET.prems e1
    by (metis new_tv_W new_tv_compatible_W new_tv_compatible_gen new_tv_subst_scheme_list)
  ultimately show ?case
    using LET.IH(2)[of R "gen ($ S A) t # $ S A" t' m] e1 subst_comp_scheme_list
    by auto
qed

theorem W_complete: 
  "[] e :: t' ==> S t m. W e [] n = Some(S,t,m) (R. t' = $ R t)"
  by (metis W_complete_lemma app_subst_Nil new_tv_Nil)

end

Messung V0.5 in Prozent
C=69 H=90 G=80

¤ Dauer der Verarbeitung: 0.8 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.