< Module mtc:lambda.
< Theorem typeOfCtx_lookups :
forall TG EG X Ty V,
typeOfCtx TG EG -> lookup TG X Ty -> lookup EG X V -> valueType V Ty.
============================
forall TG EG X Ty V,
typeOfCtx TG EG -> lookup TG X Ty -> lookup EG X V -> valueType V Ty
< induction on 2.
IH : forall TG EG X Ty V,
typeOfCtx TG EG -> lookup TG X Ty * -> lookup EG X V -> valueType V Ty
============================
forall TG EG X Ty V,
typeOfCtx TG EG -> lookup TG X Ty @ -> lookup EG X V -> valueType V Ty
< intros TOC LT LV.
Variables: TG EG X Ty V
IH : forall TG EG X Ty V,
typeOfCtx TG EG -> lookup TG X Ty * -> lookup EG X V -> valueType V Ty
TOC : typeOfCtx TG EG
LT : lookup TG X Ty @
LV : lookup EG X V
============================
valueType V Ty
< LT: case LT.
Subgoal 1:
Variables: EG X Ty V Rest
IH : forall TG EG X Ty V,
typeOfCtx TG EG -> lookup TG X Ty * -> lookup EG X V -> valueType V Ty
TOC : typeOfCtx ((X, Ty)::Rest) EG
LV : lookup EG X V
============================
valueType V Ty
< LV: case LV.
Subgoal 1.1:
Variables: X Ty V Rest Rest1
IH : forall TG EG X Ty V,
typeOfCtx TG EG -> lookup TG X Ty * -> lookup EG X V -> valueType V Ty
TOC : typeOfCtx ((X, Ty)::Rest) ((X, V)::Rest1)
============================
valueType V Ty
< case TOC.
Subgoal 1.1:
Variables: X Ty V Rest Rest1
IH : forall TG EG X Ty V,
typeOfCtx TG EG -> lookup TG X Ty * -> lookup EG X V -> valueType V Ty
H1 : valueType V Ty
H2 : typeOfCtx Rest Rest1
============================
valueType V Ty
< search.
Subgoal 1.2:
Variables: X Ty V Rest Rest1 V1 K
IH : forall TG EG X Ty V,
typeOfCtx TG EG -> lookup TG X Ty * -> lookup EG X V -> valueType V Ty
TOC : typeOfCtx ((X, Ty)::Rest) ((K, V1)::Rest1)
LV : K = X -> false
LV1 : lookup Rest1 X V
============================
valueType V Ty
< case TOC.
Subgoal 1.2:
Variables: Ty V Rest Rest1 V1 K
IH : forall TG EG X Ty V,
typeOfCtx TG EG -> lookup TG X Ty * -> lookup EG X V -> valueType V Ty
LV : K = K -> false
LV1 : lookup Rest1 K V
H1 : valueType V1 Ty
H2 : typeOfCtx Rest Rest1
============================
valueType V Ty
< apply LV to _.
Subgoal 2:
Variables: EG X Ty V Rest V1 K
IH : forall TG EG X Ty V,
typeOfCtx TG EG -> lookup TG X Ty * -> lookup EG X V -> valueType V Ty
TOC : typeOfCtx ((K, V1)::Rest) EG
LV : lookup EG X V
LT : K = X -> false
LT1 : lookup Rest X Ty *
============================
valueType V Ty
< LV: case LV.
Subgoal 2.1:
Variables: X Ty V Rest V1 K Rest1
IH : forall TG EG X Ty V,
typeOfCtx TG EG -> lookup TG X Ty * -> lookup EG X V -> valueType V Ty
TOC : typeOfCtx ((K, V1)::Rest) ((X, V)::Rest1)
LT : K = X -> false
LT1 : lookup Rest X Ty *
============================
valueType V Ty
< case TOC.
Subgoal 2.1:
Variables: X Ty V Rest V1 Rest1
IH : forall TG EG X Ty V,
typeOfCtx TG EG -> lookup TG X Ty * -> lookup EG X V -> valueType V Ty
LT : X = X -> false
LT1 : lookup Rest X Ty *
H1 : valueType V V1
H2 : typeOfCtx Rest Rest1
============================
valueType V Ty
< apply LT to _.
Subgoal 2.2:
Variables: X Ty V Rest V1 K Rest1 V2 K1
IH : forall TG EG X Ty V,
typeOfCtx TG EG -> lookup TG X Ty * -> lookup EG X V -> valueType V Ty
TOC : typeOfCtx ((K, V1)::Rest) ((K1, V2)::Rest1)
LT : K = X -> false
LT1 : lookup Rest X Ty *
LV : K1 = X -> false
LV1 : lookup Rest1 X V
============================
valueType V Ty
< TOC: case TOC.
Subgoal 2.2:
Variables: X Ty V Rest V1 Rest1 V2 K1
IH : forall TG EG X Ty V,
typeOfCtx TG EG -> lookup TG X Ty * -> lookup EG X V -> valueType V Ty
LT : K1 = X -> false
LT1 : lookup Rest X Ty *
LV : K1 = X -> false
LV1 : lookup Rest1 X V
TOC : valueType V2 V1
TOC1 : typeOfCtx Rest Rest1
============================
valueType V Ty
< apply IH to _ LT1 LV1.
Subgoal 2.2:
Variables: X Ty V Rest V1 Rest1 V2 K1
IH : forall TG EG X Ty V,
typeOfCtx TG EG -> lookup TG X Ty * -> lookup EG X V -> valueType V Ty
LT : K1 = X -> false
LT1 : lookup Rest X Ty *
LV : K1 = X -> false
LV1 : lookup Rest1 X V
TOC : valueType V2 V1
TOC1 : typeOfCtx Rest Rest1
H1 : valueType V Ty
============================
valueType V Ty
< search.
Proof completed.
< Prove mtc:shared_declarations:type_preservation.
Subgoal 1:
Variables: TG Ty EG E1 X Ty1
IH : forall TG E Ty EG V,
typeOfCtx TG EG -> typeOf TG E Ty -> eval EG E V * -> valueType V Ty
Rel : typeOfCtx TG EG
Ty : typeOf TG (abs X Ty1 E1) Ty
Ev : eval EG (abs X Ty1 E1) (closure EG X E1) @
============================
valueType (closure EG X E1) Ty
< case Ty.
Subgoal 1:
Variables: TG EG E1 X Ty1 Ty3
IH : forall TG E Ty EG V,
typeOfCtx TG EG -> typeOf TG E Ty -> eval EG E V * -> valueType V Ty
Rel : typeOfCtx TG EG
Ev : eval EG (abs X Ty1 E1) (closure EG X E1) @
H1 : typeOf ((X, Ty1)::TG) E1 Ty3
============================
valueType (closure EG X E1) (arrowTy Ty1 Ty3)
< search.
Subgoal 2:
Variables: TG Ty EG V GC X Body V2 E2 E1
IH : forall TG E Ty EG V,
typeOfCtx TG EG -> typeOf TG E Ty -> eval EG E V * -> valueType V Ty
Rel : typeOfCtx TG EG
Ty : typeOf TG (app E1 E2) Ty
Ev : eval EG (app E1 E2) V @
Ev1 : eval EG E1 (closure GC X Body) *
Ev2 : eval EG E2 V2 *
Ev3 : eval ((X, V2)::GC) Body V *
============================
valueType V Ty
< Ty: case Ty.
Subgoal 2:
Variables: TG Ty EG V GC X Body V2 E2 E1 Ty1
IH : forall TG E Ty EG V,
typeOfCtx TG EG -> typeOf TG E Ty -> eval EG E V * -> valueType V Ty
Rel : typeOfCtx TG EG
Ev : eval EG (app E1 E2) V @
Ev1 : eval EG E1 (closure GC X Body) *
Ev2 : eval EG E2 V2 *
Ev3 : eval ((X, V2)::GC) Body V *
Ty : typeOf TG E1 (arrowTy Ty1 Ty)
Ty1 : typeOf TG E2 Ty1
============================
valueType V Ty
< VT1: apply IH to _ Ty Ev1.
Subgoal 2:
Variables: TG Ty EG V GC X Body V2 E2 E1 Ty1
IH : forall TG E Ty EG V,
typeOfCtx TG EG -> typeOf TG E Ty -> eval EG E V * -> valueType V Ty
Rel : typeOfCtx TG EG
Ev : eval EG (app E1 E2) V @
Ev1 : eval EG E1 (closure GC X Body) *
Ev2 : eval EG E2 V2 *
Ev3 : eval ((X, V2)::GC) Body V *
Ty : typeOf TG E1 (arrowTy Ty1 Ty)
Ty1 : typeOf TG E2 Ty1
VT1 : valueType (closure GC X Body) (arrowTy Ty1 Ty)
============================
valueType V Ty
< VT2: apply IH to _ Ty1 Ev2.
Subgoal 2:
Variables: TG Ty EG V GC X Body V2 E2 E1 Ty1
IH : forall TG E Ty EG V,
typeOfCtx TG EG -> typeOf TG E Ty -> eval EG E V * -> valueType V Ty
Rel : typeOfCtx TG EG
Ev : eval EG (app E1 E2) V @
Ev1 : eval EG E1 (closure GC X Body) *
Ev2 : eval EG E2 V2 *
Ev3 : eval ((X, V2)::GC) Body V *
Ty : typeOf TG E1 (arrowTy Ty1 Ty)
Ty1 : typeOf TG E2 Ty1
VT1 : valueType (closure GC X Body) (arrowTy Ty1 Ty)
VT2 : valueType V2 Ty1
============================
valueType V Ty
< VTC: case VT1.
Subgoal 2:
Variables: TG Ty EG V GC X Body V2 E2 E1 Ty1 TG1
IH : forall TG E Ty EG V,
typeOfCtx TG EG -> typeOf TG E Ty -> eval EG E V * -> valueType V Ty
Rel : typeOfCtx TG EG
Ev : eval EG (app E1 E2) V @
Ev1 : eval EG E1 (closure GC X Body) *
Ev2 : eval EG E2 V2 *
Ev3 : eval ((X, V2)::GC) Body V *
Ty : typeOf TG E1 (arrowTy Ty1 Ty)
Ty1 : typeOf TG E2 Ty1
VT2 : valueType V2 Ty1
VTC : typeOfCtx TG1 GC
VTC1 : typeOf ((X, Ty1)::TG1) Body Ty
============================
valueType V Ty
< apply IH to _ VTC1 Ev3.
Subgoal 2:
Variables: TG Ty EG V GC X Body V2 E2 E1 Ty1 TG1
IH : forall TG E Ty EG V,
typeOfCtx TG EG -> typeOf TG E Ty -> eval EG E V * -> valueType V Ty
Rel : typeOfCtx TG EG
Ev : eval EG (app E1 E2) V @
Ev1 : eval EG E1 (closure GC X Body) *
Ev2 : eval EG E2 V2 *
Ev3 : eval ((X, V2)::GC) Body V *
Ty : typeOf TG E1 (arrowTy Ty1 Ty)
Ty1 : typeOf TG E2 Ty1
VT2 : valueType V2 Ty1
VTC : typeOfCtx TG1 GC
VTC1 : typeOf ((X, Ty1)::TG1) Body Ty
H1 : valueType V Ty
============================
valueType V Ty
< search.
Subgoal 3:
Variables: TG Ty EG V X
IH : forall TG E Ty EG V,
typeOfCtx TG EG -> typeOf TG E Ty -> eval EG E V * -> valueType V Ty
Rel : typeOfCtx TG EG
Ty : typeOf TG (var X) Ty
Ev : eval EG (var X) V @
Ev1 : lookup EG X V
============================
valueType V Ty
< Ty: case Ty.
Subgoal 3:
Variables: TG Ty EG V X
IH : forall TG E Ty EG V,
typeOfCtx TG EG -> typeOf TG E Ty -> eval EG E V * -> valueType V Ty
Rel : typeOfCtx TG EG
Ev : eval EG (var X) V @
Ev1 : lookup EG X V
Ty : lookup TG X Ty
============================
valueType V Ty
< apply typeOfCtx_lookups to _ Ty Ev1.
Subgoal 3:
Variables: TG Ty EG V X
IH : forall TG E Ty EG V,
typeOfCtx TG EG -> typeOf TG E Ty -> eval EG E V * -> valueType V Ty
Rel : typeOfCtx TG EG
Ev : eval EG (var X) V @
Ev1 : lookup EG X V
Ty : lookup TG X Ty
H1 : valueType V Ty
============================
valueType V Ty
< search.
Proof completed.
< Prove mtc:shared_declarations:value_evalStep_false.
Subgoal 1:
Variables: E' E1 Ty X
IH : forall E E', value E * -> evalStep E E' -> false
V : value (abs X Ty E1) @
Ev : evalStep (abs X Ty E1) E'
============================
false
< case Ev.
Proof completed.
< Prove mtc:shared_declarations:subst_unique.
Subgoal 1:
Variables: X R EB E1 Ty
IH : forall X R E EA EB, subst X R E EA * -> subst X R E EB -> EA = EB
SA : subst X R (abs X Ty E1) (abs X Ty E1) @
SB : subst X R (abs X Ty E1) EB
============================
abs X Ty E1 = EB
< SB: case SB.
Subgoal 1.1:
Variables: X R E1 Ty
IH : forall X R E EA EB, subst X R E EA * -> subst X R E EB -> EA = EB
SA : subst X R (abs X Ty E1) (abs X Ty E1) @
============================
abs X Ty E1 = abs X Ty E1
< search.
Subgoal 1.2:
Variables: X R E1 Ty E3
IH : forall X R E EA EB, subst X R E EA * -> subst X R E EB -> EA = EB
SA : subst X R (abs X Ty E1) (abs X Ty E1) @
SB : X = X -> false
SB1 : subst X R E1 E3
============================
abs X Ty E1 = abs X Ty E3
< apply SB to _.
Subgoal 2:
Variables: X R EB E2 Ty Y E1
IH : forall X R E EA EB, subst X R E EA * -> subst X R E EB -> EA = EB
SA : subst X R (abs Y Ty E1) (abs Y Ty E2) @
SB : subst X R (abs Y Ty E1) EB
SA1 : X = Y -> false
SA2 : subst X R E1 E2 *
============================
abs Y Ty E2 = EB
< SB: case SB.
Subgoal 2.1:
Variables: R E2 Ty Y E1
IH : forall X R E EA EB, subst X R E EA * -> subst X R E EB -> EA = EB
SA : subst Y R (abs Y Ty E1) (abs Y Ty E2) @
SA1 : Y = Y -> false
SA2 : subst Y R E1 E2 *
============================
abs Y Ty E2 = abs Y Ty E1
< apply SA1 to _.
Subgoal 2.2:
Variables: X R E2 Ty Y E1 E4
IH : forall X R E EA EB, subst X R E EA * -> subst X R E EB -> EA = EB
SA : subst X R (abs Y Ty E1) (abs Y Ty E2) @
SA1 : X = Y -> false
SA2 : subst X R E1 E2 *
SB : X = Y -> false
SB1 : subst X R E1 E4
============================
abs Y Ty E2 = abs Y Ty E4
< apply IH to SA2 SB1.
Subgoal 2.2:
Variables: X R Ty Y E1 E4
IH : forall X R E EA EB, subst X R E EA * -> subst X R E EB -> EA = EB
SA : subst X R (abs Y Ty E1) (abs Y Ty E4) @
SA1 : X = Y -> false
SA2 : subst X R E1 E4 *
SB : X = Y -> false
SB1 : subst X R E1 E4
============================
abs Y Ty E4 = abs Y Ty E4
< search.
Subgoal 3:
Variables: X R EB E21 E11 E2 E1
IH : forall X R E EA EB, subst X R E EA * -> subst X R E EB -> EA = EB
SA : subst X R (app E1 E2) (app E11 E21) @
SB : subst X R (app E1 E2) EB
SA1 : subst X R E1 E11 *
SA2 : subst X R E2 E21 *
============================
app E11 E21 = EB
< SB: case SB.
Subgoal 3:
Variables: X R E21 E11 E2 E1 E6 E5
IH : forall X R E EA EB, subst X R E EA * -> subst X R E EB -> EA = EB
SA : subst X R (app E1 E2) (app E11 E21) @
SA1 : subst X R E1 E11 *
SA2 : subst X R E2 E21 *
SB : subst X R E1 E5
SB1 : subst X R E2 E6
============================
app E11 E21 = app E5 E6
< apply IH to SA1 SB.
Subgoal 3:
Variables: X R E21 E2 E1 E6 E5
IH : forall X R E EA EB, subst X R E EA * -> subst X R E EB -> EA = EB
SA : subst X R (app E1 E2) (app E5 E21) @
SA1 : subst X R E1 E5 *
SA2 : subst X R E2 E21 *
SB : subst X R E1 E5
SB1 : subst X R E2 E6
============================
app E5 E21 = app E5 E6
< apply IH to SA2 SB1.
Subgoal 3:
Variables: X R E2 E1 E6 E5
IH : forall X R E EA EB, subst X R E EA * -> subst X R E EB -> EA = EB
SA : subst X R (app E1 E2) (app E5 E6) @
SA1 : subst X R E1 E5 *
SA2 : subst X R E2 E6 *
SB : subst X R E1 E5
SB1 : subst X R E2 E6
============================
app E5 E6 = app E5 E6
< search.
Subgoal 4:
Variables: X EA EB
IH : forall X R E EA EB, subst X R E EA * -> subst X R E EB -> EA = EB
SA : subst X EA (var X) EA @
SB : subst X EA (var X) EB
============================
EA = EB
< SB: case SB.
Subgoal 4.1:
Variables: X EB
IH : forall X R E EA EB, subst X R E EA * -> subst X R E EB -> EA = EB
SA : subst X EB (var X) EB @
============================
EB = EB
< search.
Subgoal 4.2:
Variables: X EA
IH : forall X R E EA EB, subst X R E EA * -> subst X R E EB -> EA = EB
SA : subst X EA (var X) EA @
SB : X = X -> false
============================
EA = var X
< apply SB to _.
Subgoal 5:
Variables: X R EB Y
IH : forall X R E EA EB, subst X R E EA * -> subst X R E EB -> EA = EB
SA : subst X R (var Y) (var Y) @
SB : subst X R (var Y) EB
SA1 : X = Y -> false
============================
var Y = EB
< SB: case SB.
Subgoal 5.1:
Variables: EB Y
IH : forall X R E EA EB, subst X R E EA * -> subst X R E EB -> EA = EB
SA : subst Y EB (var Y) (var Y) @
SA1 : Y = Y -> false
============================
var Y = EB
< apply SA1 to _.
Subgoal 5.2:
Variables: X R Y
IH : forall X R E EA EB, subst X R E EA * -> subst X R E EB -> EA = EB
SA : subst X R (var Y) (var Y) @
SA1 : X = Y -> false
SB : X = Y -> false
============================
var Y = var Y
< search.
Proof completed.
< Prove mtc:shared_declarations:evalStep_unique.
Subgoal 1:
Variables: EB E2 E11 E1
IH : forall E EA EB, evalStep E EA * -> evalStep E EB -> EA = EB
EvA : evalStep (app E1 E2) (app E11 E2) @
EvB : evalStep (app E1 E2) EB
EvA1 : evalStep E1 E11 *
============================
app E11 E2 = EB
< EvB: case EvB.
Subgoal 1.1:
Variables: E2 E11 E1 E5
IH : forall E EA EB, evalStep E EA * -> evalStep E EB -> EA = EB
EvA : evalStep (app E1 E2) (app E11 E2) @
EvA1 : evalStep E1 E11 *
EvB : evalStep E1 E5
============================
app E11 E2 = app E5 E2
< apply IH to EvA1 EvB.
Subgoal 1.1:
Variables: E2 E1 E5
IH : forall E EA EB, evalStep E EA * -> evalStep E EB -> EA = EB
EvA : evalStep (app E1 E2) (app E5 E2) @
EvA1 : evalStep E1 E5 *
EvB : evalStep E1 E5
============================
app E5 E2 = app E5 E2
< search.
Subgoal 1.2:
Variables: E2 E11 E1 E21
IH : forall E EA EB, evalStep E EA * -> evalStep E EB -> EA = EB
EvA : evalStep (app E1 E2) (app E11 E2) @
EvA1 : evalStep E1 E11 *
EvB : value E1
EvB1 : evalStep E2 E21
============================
app E11 E2 = app E1 E21
< apply value_evalStep_false to EvB EvA1.
Subgoal 1.3:
Variables: EB E2 E11 E3 Ty X
IH : forall E EA EB, evalStep E EA * -> evalStep E EB -> EA = EB
EvA : evalStep (app (abs X Ty E3) E2) (app E11 E2) @
EvA1 : evalStep (abs X Ty E3) E11 *
EvB : value E2
EvB1 : subst X E2 E3 EB
============================
app E11 E2 = EB
< case EvA1.
Subgoal 2:
Variables: EB E21 E1 E2
IH : forall E EA EB, evalStep E EA * -> evalStep E EB -> EA = EB
EvA : evalStep (app E1 E2) (app E1 E21) @
EvB : evalStep (app E1 E2) EB
EvA1 : value E1
EvA2 : evalStep E2 E21 *
============================
app E1 E21 = EB
< EvB: case EvB.
Subgoal 2.1:
Variables: E21 E1 E2 E11
IH : forall E EA EB, evalStep E EA * -> evalStep E EB -> EA = EB
EvA : evalStep (app E1 E2) (app E1 E21) @
EvA1 : value E1
EvA2 : evalStep E2 E21 *
EvB : evalStep E1 E11
============================
app E1 E21 = app E11 E2
< apply value_evalStep_false to EvA1 EvB.
Subgoal 2.2:
Variables: E21 E1 E2 E5
IH : forall E EA EB, evalStep E EA * -> evalStep E EB -> EA = EB
EvA : evalStep (app E1 E2) (app E1 E21) @
EvA1 : value E1
EvA2 : evalStep E2 E21 *
EvB : value E1
EvB1 : evalStep E2 E5
============================
app E1 E21 = app E1 E5
< apply IH to EvA2 EvB1.
Subgoal 2.2:
Variables: E1 E2 E5
IH : forall E EA EB, evalStep E EA * -> evalStep E EB -> EA = EB
EvA : evalStep (app E1 E2) (app E1 E5) @
EvA1 : value E1
EvA2 : evalStep E2 E5 *
EvB : value E1
EvB1 : evalStep E2 E5
============================
app E1 E5 = app E1 E5
< search.
Subgoal 2.3:
Variables: EB E21 E2 E3 Ty X
IH : forall E EA EB, evalStep E EA * -> evalStep E EB -> EA = EB
EvA : evalStep (app (abs X Ty E3) E2) (app (abs X Ty E3) E21) @
EvA1 : value (abs X Ty E3)
EvA2 : evalStep E2 E21 *
EvB : value E2
EvB1 : subst X E2 E3 EB
============================
app (abs X Ty E3) E21 = EB
< apply value_evalStep_false to EvB EvA2.
Subgoal 3:
Variables: EA EB E2 E1 Ty X
IH : forall E EA EB, evalStep E EA * -> evalStep E EB -> EA = EB
EvA : evalStep (app (abs X Ty E1) E2) EA @
EvB : evalStep (app (abs X Ty E1) E2) EB
EvA1 : value E2
EvA2 : subst X E2 E1 EA
============================
EA = EB
< EvB: case EvB.
Subgoal 3.1:
Variables: EA E2 E1 Ty X E11
IH : forall E EA EB, evalStep E EA * -> evalStep E EB -> EA = EB
EvA : evalStep (app (abs X Ty E1) E2) EA @
EvA1 : value E2
EvA2 : subst X E2 E1 EA
EvB : evalStep (abs X Ty E1) E11
============================
EA = app E11 E2
< case EvB.
Subgoal 3.2:
Variables: EA E2 E1 Ty X E21
IH : forall E EA EB, evalStep E EA * -> evalStep E EB -> EA = EB
EvA : evalStep (app (abs X Ty E1) E2) EA @
EvA1 : value E2
EvA2 : subst X E2 E1 EA
EvB : value (abs X Ty E1)
EvB1 : evalStep E2 E21
============================
EA = app (abs X Ty E1) E21
< apply value_evalStep_false to EvA1 EvB1.
Subgoal 3.3:
Variables: EA EB E2 E1 Ty X
IH : forall E EA EB, evalStep E EA * -> evalStep E EB -> EA = EB
EvA : evalStep (app (abs X Ty E1) E2) EA @
EvA1 : value E2
EvA2 : subst X E2 E1 EA
EvB : value E2
EvB1 : subst X E2 E1 EB
============================
EA = EB
< apply subst_unique to EvA2 EvB1.
Subgoal 3.3:
Variables: EB E2 E1 Ty X
IH : forall E EA EB, evalStep E EA * -> evalStep E EB -> EA = EB
EvA : evalStep (app (abs X Ty E1) E2) EB @
EvA1 : value E2
EvA2 : subst X E2 E1 EB
EvB : value E2
EvB1 : subst X E2 E1 EB
============================
EB = EB
< search.
Proof completed.
< Prove mtc:shared_declarations:ty_lookup.
Subgoal 1:
Variables: G1 G2 Ty2 Ty1 E1 X
IH : forall G1 G2 E Ty,
typeOf G1 E Ty * -> (forall X XTy, lookup G1 X XTy -> lookup G2 X XTy) ->
typeOf G2 E Ty
Ty : typeOf G1 (abs X Ty1 E1) (arrowTy Ty1 Ty2) @
L : forall X XTy, lookup G1 X XTy -> lookup G2 X XTy
Ty1 : typeOf ((X, Ty1)::G1) E1 Ty2 *
============================
typeOf G2 (abs X Ty1 E1) (arrowTy Ty1 Ty2)
< apply IH to Ty1 _ with
G2 = (X, Ty1)::G2.
Subgoal 1.1:
Variables: G1 G2 Ty2 Ty1 E1 X
IH : forall G1 G2 E Ty,
typeOf G1 E Ty * -> (forall X XTy, lookup G1 X XTy -> lookup G2 X XTy) ->
typeOf G2 E Ty
Ty : typeOf G1 (abs X Ty1 E1) (arrowTy Ty1 Ty2) @
L : forall X XTy, lookup G1 X XTy -> lookup G2 X XTy
Ty1 : typeOf ((X, Ty1)::G1) E1 Ty2 *
============================
forall X1 XTy, lookup ((X, Ty1)::G1) X1 XTy -> lookup ((X, Ty1)::G2) X1 XTy
< intros L'.
Subgoal 1.1:
Variables: G1 G2 Ty2 Ty1 E1 X X1 XTy
IH : forall G1 G2 E Ty,
typeOf G1 E Ty * -> (forall X XTy, lookup G1 X XTy -> lookup G2 X XTy) ->
typeOf G2 E Ty
Ty : typeOf G1 (abs X Ty1 E1) (arrowTy Ty1 Ty2) @
L : forall X XTy, lookup G1 X XTy -> lookup G2 X XTy
Ty1 : typeOf ((X, Ty1)::G1) E1 Ty2 *
L' : lookup ((X, Ty1)::G1) X1 XTy
============================
lookup ((X, Ty1)::G2) X1 XTy
< L': case L'.
Subgoal 1.1.1:
Variables: G1 G2 Ty2 E1 X1 XTy
IH : forall G1 G2 E Ty,
typeOf G1 E Ty * -> (forall X XTy, lookup G1 X XTy -> lookup G2 X XTy) ->
typeOf G2 E Ty
Ty : typeOf G1 (abs X1 XTy E1) (arrowTy XTy Ty2) @
L : forall X XTy, lookup G1 X XTy -> lookup G2 X XTy
Ty1 : typeOf ((X1, XTy)::G1) E1 Ty2 *
============================
lookup ((X1, XTy)::G2) X1 XTy
< search.
Subgoal 1.1.2:
Variables: G1 G2 Ty2 Ty1 E1 X X1 XTy
IH : forall G1 G2 E Ty,
typeOf G1 E Ty * -> (forall X XTy, lookup G1 X XTy -> lookup G2 X XTy) ->
typeOf G2 E Ty
Ty : typeOf G1 (abs X Ty1 E1) (arrowTy Ty1 Ty2) @
L : forall X XTy, lookup G1 X XTy -> lookup G2 X XTy
Ty1 : typeOf ((X, Ty1)::G1) E1 Ty2 *
L' : X = X1 -> false
L'1 : lookup G1 X1 XTy
============================
lookup ((X, Ty1)::G2) X1 XTy
< apply L to L'1.
Subgoal 1.1.2:
Variables: G1 G2 Ty2 Ty1 E1 X X1 XTy
IH : forall G1 G2 E Ty,
typeOf G1 E Ty * -> (forall X XTy, lookup G1 X XTy -> lookup G2 X XTy) ->
typeOf G2 E Ty
Ty : typeOf G1 (abs X Ty1 E1) (arrowTy Ty1 Ty2) @
L : forall X XTy, lookup G1 X XTy -> lookup G2 X XTy
Ty1 : typeOf ((X, Ty1)::G1) E1 Ty2 *
L' : X = X1 -> false
L'1 : lookup G1 X1 XTy
H1 : lookup G2 X1 XTy
============================
lookup ((X, Ty1)::G2) X1 XTy
< search.
Subgoal 1:
Variables: G1 G2 Ty2 Ty1 E1 X
IH : forall G1 G2 E Ty,
typeOf G1 E Ty * -> (forall X XTy, lookup G1 X XTy -> lookup G2 X XTy) ->
typeOf G2 E Ty
Ty : typeOf G1 (abs X Ty1 E1) (arrowTy Ty1 Ty2) @
L : forall X XTy, lookup G1 X XTy -> lookup G2 X XTy
Ty1 : typeOf ((X, Ty1)::G1) E1 Ty2 *
H1 : typeOf ((X, Ty1)::G2) E1 Ty2
============================
typeOf G2 (abs X Ty1 E1) (arrowTy Ty1 Ty2)
< search.
Subgoal 2:
Variables: G1 G2 Ty Ty1 E2 E1
IH : forall G1 G2 E Ty,
typeOf G1 E Ty * -> (forall X XTy, lookup G1 X XTy -> lookup G2 X XTy) ->
typeOf G2 E Ty
Ty : typeOf G1 (app E1 E2) Ty @
L : forall X XTy, lookup G1 X XTy -> lookup G2 X XTy
Ty1 : typeOf G1 E1 (arrowTy Ty1 Ty) *
Ty2 : typeOf G1 E2 Ty1 *
============================
typeOf G2 (app E1 E2) Ty
< apply IH to Ty1 L.
Subgoal 2:
Variables: G1 G2 Ty Ty1 E2 E1
IH : forall G1 G2 E Ty,
typeOf G1 E Ty * -> (forall X XTy, lookup G1 X XTy -> lookup G2 X XTy) ->
typeOf G2 E Ty
Ty : typeOf G1 (app E1 E2) Ty @
L : forall X XTy, lookup G1 X XTy -> lookup G2 X XTy
Ty1 : typeOf G1 E1 (arrowTy Ty1 Ty) *
Ty2 : typeOf G1 E2 Ty1 *
H1 : typeOf G2 E1 (arrowTy Ty1 Ty)
============================
typeOf G2 (app E1 E2) Ty
< apply IH to Ty2 L.
Subgoal 2:
Variables: G1 G2 Ty Ty1 E2 E1
IH : forall G1 G2 E Ty,
typeOf G1 E Ty * -> (forall X XTy, lookup G1 X XTy -> lookup G2 X XTy) ->
typeOf G2 E Ty
Ty : typeOf G1 (app E1 E2) Ty @
L : forall X XTy, lookup G1 X XTy -> lookup G2 X XTy
Ty1 : typeOf G1 E1 (arrowTy Ty1 Ty) *
Ty2 : typeOf G1 E2 Ty1 *
H1 : typeOf G2 E1 (arrowTy Ty1 Ty)
H2 : typeOf G2 E2 Ty1
============================
typeOf G2 (app E1 E2) Ty
< search.
Subgoal 3:
Variables: G1 G2 Ty X
IH : forall G1 G2 E Ty,
typeOf G1 E Ty * -> (forall X XTy, lookup G1 X XTy -> lookup G2 X XTy) ->
typeOf G2 E Ty
Ty : typeOf G1 (var X) Ty @
L : forall X XTy, lookup G1 X XTy -> lookup G2 X XTy
Ty1 : lookup G1 X Ty
============================
typeOf G2 (var X) Ty
< apply L to Ty1.
Subgoal 3:
Variables: G1 G2 Ty X
IH : forall G1 G2 E Ty,
typeOf G1 E Ty * -> (forall X XTy, lookup G1 X XTy -> lookup G2 X XTy) ->
typeOf G2 E Ty
Ty : typeOf G1 (var X) Ty @
L : forall X XTy, lookup G1 X XTy -> lookup G2 X XTy
Ty1 : lookup G1 X Ty
H1 : lookup G2 X Ty
============================
typeOf G2 (var X) Ty
< search.
Proof completed.
< Prove mtc:shared_declarations:subst_preservation.
Subgoal 1:
Variables: X XTy TG Ty R E1 Ty1
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
Ty : typeOf ((X, XTy)::TG) (abs X Ty1 E1) Ty
S : subst X R (abs X Ty1 E1) (abs X Ty1 E1) @
RTy : typeOf [] R XTy
============================
typeOf TG (abs X Ty1 E1) Ty
< Ty: case Ty.
Subgoal 1:
Variables: X XTy TG R E1 Ty1 Ty3
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X R (abs X Ty1 E1) (abs X Ty1 E1) @
RTy : typeOf [] R XTy
Ty : typeOf ((X, Ty1)::((X, XTy)::TG)) E1 Ty3
============================
typeOf TG (abs X Ty1 E1) (arrowTy Ty1 Ty3)
< apply ty_lookup to Ty _ with
G2 = (X, Ty1)::TG.
Subgoal 1.1:
Variables: X XTy TG R E1 Ty1 Ty3
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X R (abs X Ty1 E1) (abs X Ty1 E1) @
RTy : typeOf [] R XTy
Ty : typeOf ((X, Ty1)::((X, XTy)::TG)) E1 Ty3
============================
forall X1 XTy1,
lookup ((X, Ty1)::((X, XTy)::TG)) X1 XTy1 -> lookup ((X, Ty1)::TG) X1 XTy1
< intros L.
Subgoal 1.1:
Variables: X XTy TG R E1 Ty1 Ty3 X1 XTy1
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X R (abs X Ty1 E1) (abs X Ty1 E1) @
RTy : typeOf [] R XTy
Ty : typeOf ((X, Ty1)::((X, XTy)::TG)) E1 Ty3
L : lookup ((X, Ty1)::((X, XTy)::TG)) X1 XTy1
============================
lookup ((X, Ty1)::TG) X1 XTy1
< L: case L.
Subgoal 1.1.1:
Variables: XTy TG R E1 Ty3 X1 XTy1
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X1 R (abs X1 XTy1 E1) (abs X1 XTy1 E1) @
RTy : typeOf [] R XTy
Ty : typeOf ((X1, XTy1)::((X1, XTy)::TG)) E1 Ty3
============================
lookup ((X1, XTy1)::TG) X1 XTy1
< search.
Subgoal 1.1.2:
Variables: X XTy TG R E1 Ty1 Ty3 X1 XTy1
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X R (abs X Ty1 E1) (abs X Ty1 E1) @
RTy : typeOf [] R XTy
Ty : typeOf ((X, Ty1)::((X, XTy)::TG)) E1 Ty3
L : X = X1 -> false
L1 : lookup ((X, XTy)::TG) X1 XTy1
============================
lookup ((X, Ty1)::TG) X1 XTy1
< L': case L1.
Subgoal 1.1.2.1:
Variables: TG R E1 Ty1 Ty3 X1 XTy1
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X1 R (abs X1 Ty1 E1) (abs X1 Ty1 E1) @
RTy : typeOf [] R XTy1
Ty : typeOf ((X1, Ty1)::((X1, XTy1)::TG)) E1 Ty3
L : X1 = X1 -> false
============================
lookup ((X1, Ty1)::TG) X1 XTy1
< apply L to _.
Subgoal 1.1.2.2:
Variables: X XTy TG R E1 Ty1 Ty3 X1 XTy1
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X R (abs X Ty1 E1) (abs X Ty1 E1) @
RTy : typeOf [] R XTy
Ty : typeOf ((X, Ty1)::((X, XTy)::TG)) E1 Ty3
L : X = X1 -> false
L' : X = X1 -> false
L'1 : lookup TG X1 XTy1
============================
lookup ((X, Ty1)::TG) X1 XTy1
< search.
Subgoal 1:
Variables: X XTy TG R E1 Ty1 Ty3
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X R (abs X Ty1 E1) (abs X Ty1 E1) @
RTy : typeOf [] R XTy
Ty : typeOf ((X, Ty1)::((X, XTy)::TG)) E1 Ty3
H1 : typeOf ((X, Ty1)::TG) E1 Ty3
============================
typeOf TG (abs X Ty1 E1) (arrowTy Ty1 Ty3)
< search.
Subgoal 2:
Variables: X XTy TG Ty R E2 Ty1 Y E1
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
Ty : typeOf ((X, XTy)::TG) (abs Y Ty1 E1) Ty
S : subst X R (abs Y Ty1 E1) (abs Y Ty1 E2) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R E1 E2 *
============================
typeOf TG (abs Y Ty1 E2) Ty
< Ty: case Ty.
Subgoal 2:
Variables: X XTy TG R E2 Ty1 Y E1 Ty3
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X R (abs Y Ty1 E1) (abs Y Ty1 E2) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R E1 E2 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::TG)) E1 Ty3
============================
typeOf TG (abs Y Ty1 E2) (arrowTy Ty1 Ty3)
< Ty': apply ty_lookup to Ty _ with
G2 = (X, XTy)::((Y, Ty1)::TG).
Subgoal 2.1:
Variables: X XTy TG R E2 Ty1 Y E1 Ty3
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X R (abs Y Ty1 E1) (abs Y Ty1 E2) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R E1 E2 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::TG)) E1 Ty3
============================
forall X1 XTy1,
lookup ((Y, Ty1)::((X, XTy)::TG)) X1 XTy1 -> lookup ((X, XTy)::((Y, Ty1)::TG)) X1 XTy1
< intros L.
Subgoal 2.1:
Variables: X XTy TG R E2 Ty1 Y E1 Ty3 X1 XTy1
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X R (abs Y Ty1 E1) (abs Y Ty1 E2) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R E1 E2 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::TG)) E1 Ty3
L : lookup ((Y, Ty1)::((X, XTy)::TG)) X1 XTy1
============================
lookup ((X, XTy)::((Y, Ty1)::TG)) X1 XTy1
< L: case L.
Subgoal 2.1.1:
Variables: X XTy TG R E2 E1 Ty3 X1 XTy1
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X R (abs X1 XTy1 E1) (abs X1 XTy1 E2) @
RTy : typeOf [] R XTy
S1 : X = X1 -> false
S2 : subst X R E1 E2 *
Ty : typeOf ((X1, XTy1)::((X, XTy)::TG)) E1 Ty3
============================
lookup ((X, XTy)::((X1, XTy1)::TG)) X1 XTy1
< search.
Subgoal 2.1.2:
Variables: X XTy TG R E2 Ty1 Y E1 Ty3 X1 XTy1
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X R (abs Y Ty1 E1) (abs Y Ty1 E2) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R E1 E2 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::TG)) E1 Ty3
L : Y = X1 -> false
L1 : lookup ((X, XTy)::TG) X1 XTy1
============================
lookup ((X, XTy)::((Y, Ty1)::TG)) X1 XTy1
< L': case L1.
Subgoal 2.1.2.1:
Variables: TG R E2 Ty1 Y E1 Ty3 X1 XTy1
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X1 R (abs Y Ty1 E1) (abs Y Ty1 E2) @
RTy : typeOf [] R XTy1
S1 : X1 = Y -> false
S2 : subst X1 R E1 E2 *
Ty : typeOf ((Y, Ty1)::((X1, XTy1)::TG)) E1 Ty3
L : Y = X1 -> false
============================
lookup ((X1, XTy1)::((Y, Ty1)::TG)) X1 XTy1
< search.
Subgoal 2.1.2.2:
Variables: X XTy TG R E2 Ty1 Y E1 Ty3 X1 XTy1
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X R (abs Y Ty1 E1) (abs Y Ty1 E2) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R E1 E2 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::TG)) E1 Ty3
L : Y = X1 -> false
L' : X = X1 -> false
L'1 : lookup TG X1 XTy1
============================
lookup ((X, XTy)::((Y, Ty1)::TG)) X1 XTy1
< search.
Subgoal 2:
Variables: X XTy TG R E2 Ty1 Y E1 Ty3
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X R (abs Y Ty1 E1) (abs Y Ty1 E2) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R E1 E2 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::TG)) E1 Ty3
Ty' : typeOf ((X, XTy)::((Y, Ty1)::TG)) E1 Ty3
============================
typeOf TG (abs Y Ty1 E2) (arrowTy Ty1 Ty3)
< apply IH to Ty' S2 RTy.
Subgoal 2:
Variables: X XTy TG R E2 Ty1 Y E1 Ty3
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X R (abs Y Ty1 E1) (abs Y Ty1 E2) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
S2 : subst X R E1 E2 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::TG)) E1 Ty3
Ty' : typeOf ((X, XTy)::((Y, Ty1)::TG)) E1 Ty3
H1 : typeOf ((Y, Ty1)::TG) E2 Ty3
============================
typeOf TG (abs Y Ty1 E2) (arrowTy Ty1 Ty3)
< search.
Subgoal 3:
Variables: X XTy TG Ty R E21 E11 E2 E1
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
Ty : typeOf ((X, XTy)::TG) (app E1 E2) Ty
S : subst X R (app E1 E2) (app E11 E21) @
RTy : typeOf [] R XTy
S1 : subst X R E1 E11 *
S2 : subst X R E2 E21 *
============================
typeOf TG (app E11 E21) Ty
< Ty: case Ty.
Subgoal 3:
Variables: X XTy TG Ty R E21 E11 E2 E1 Ty1
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X R (app E1 E2) (app E11 E21) @
RTy : typeOf [] R XTy
S1 : subst X R E1 E11 *
S2 : subst X R E2 E21 *
Ty : typeOf ((X, XTy)::TG) E1 (arrowTy Ty1 Ty)
Ty1 : typeOf ((X, XTy)::TG) E2 Ty1
============================
typeOf TG (app E11 E21) Ty
< apply IH to Ty S1 RTy.
Subgoal 3:
Variables: X XTy TG Ty R E21 E11 E2 E1 Ty1
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X R (app E1 E2) (app E11 E21) @
RTy : typeOf [] R XTy
S1 : subst X R E1 E11 *
S2 : subst X R E2 E21 *
Ty : typeOf ((X, XTy)::TG) E1 (arrowTy Ty1 Ty)
Ty1 : typeOf ((X, XTy)::TG) E2 Ty1
H1 : typeOf TG E11 (arrowTy Ty1 Ty)
============================
typeOf TG (app E11 E21) Ty
< apply IH to Ty1 S2 RTy.
Subgoal 3:
Variables: X XTy TG Ty R E21 E11 E2 E1 Ty1
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X R (app E1 E2) (app E11 E21) @
RTy : typeOf [] R XTy
S1 : subst X R E1 E11 *
S2 : subst X R E2 E21 *
Ty : typeOf ((X, XTy)::TG) E1 (arrowTy Ty1 Ty)
Ty1 : typeOf ((X, XTy)::TG) E2 Ty1
H1 : typeOf TG E11 (arrowTy Ty1 Ty)
H2 : typeOf TG E21 Ty1
============================
typeOf TG (app E11 E21) Ty
< search.
Subgoal 4:
Variables: X XTy TG Ty E'
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
Ty : typeOf ((X, XTy)::TG) (var X) Ty
S : subst X E' (var X) E' @
RTy : typeOf [] E' XTy
============================
typeOf TG E' Ty
< Ty: case Ty.
Subgoal 4:
Variables: X XTy TG Ty E'
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X E' (var X) E' @
RTy : typeOf [] E' XTy
Ty : lookup ((X, XTy)::TG) X Ty
============================
typeOf TG E' Ty
< L: case Ty.
Subgoal 4.1:
Variables: X TG Ty E'
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X E' (var X) E' @
RTy : typeOf [] E' Ty
============================
typeOf TG E' Ty
< backchain empty_ty_any.
Subgoal 4.2:
Variables: X XTy TG Ty E'
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X E' (var X) E' @
RTy : typeOf [] E' XTy
L : X = X -> false
L1 : lookup TG X Ty
============================
typeOf TG E' Ty
< apply L to _.
Subgoal 5:
Variables: X XTy TG Ty R Y
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
Ty : typeOf ((X, XTy)::TG) (var Y) Ty
S : subst X R (var Y) (var Y) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
============================
typeOf TG (var Y) Ty
< Ty: case Ty.
Subgoal 5:
Variables: X XTy TG Ty R Y
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X R (var Y) (var Y) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
Ty : lookup ((X, XTy)::TG) Y Ty
============================
typeOf TG (var Y) Ty
< L: case Ty.
Subgoal 5.1:
Variables: TG Ty R Y
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst Y R (var Y) (var Y) @
RTy : typeOf [] R Ty
S1 : Y = Y -> false
============================
typeOf TG (var Y) Ty
< apply S1 to _.
Subgoal 5.2:
Variables: X XTy TG Ty R Y
IH : forall X XTy TG E Ty R E',
typeOf ((X, XTy)::TG) E Ty -> subst X R E E' * -> typeOf [] R XTy -> typeOf TG E' Ty
S : subst X R (var Y) (var Y) @
RTy : typeOf [] R XTy
S1 : X = Y -> false
L : X = Y -> false
L1 : lookup TG Y Ty
============================
typeOf TG (var Y) Ty
< search.
Proof completed.
< Prove mtc:shared_declarations:evalStep_type_preservation.
Subgoal 1:
Variables: Ty E2 E11 E1
IH : forall E Ty E', typeOf [] E Ty -> evalStep E E' * -> typeOf [] E' Ty
Ty : typeOf [] (app E1 E2) Ty
Ev : evalStep (app E1 E2) (app E11 E2) @
Ev1 : evalStep E1 E11 *
============================
typeOf [] (app E11 E2) Ty
< Ty: case Ty.
Subgoal 1:
Variables: Ty E2 E11 E1 Ty1
IH : forall E Ty E', typeOf [] E Ty -> evalStep E E' * -> typeOf [] E' Ty
Ev : evalStep (app E1 E2) (app E11 E2) @
Ev1 : evalStep E1 E11 *
Ty : typeOf [] E1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] E2 Ty1
============================
typeOf [] (app E11 E2) Ty
< apply IH to Ty Ev1.
Subgoal 1:
Variables: Ty E2 E11 E1 Ty1
IH : forall E Ty E', typeOf [] E Ty -> evalStep E E' * -> typeOf [] E' Ty
Ev : evalStep (app E1 E2) (app E11 E2) @
Ev1 : evalStep E1 E11 *
Ty : typeOf [] E1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] E2 Ty1
H1 : typeOf [] E11 (arrowTy Ty1 Ty)
============================
typeOf [] (app E11 E2) Ty
< search.
Subgoal 2:
Variables: Ty E21 E1 E2
IH : forall E Ty E', typeOf [] E Ty -> evalStep E E' * -> typeOf [] E' Ty
Ty : typeOf [] (app E1 E2) Ty
Ev : evalStep (app E1 E2) (app E1 E21) @
Ev1 : value E1
Ev2 : evalStep E2 E21 *
============================
typeOf [] (app E1 E21) Ty
< Ty: case Ty.
Subgoal 2:
Variables: Ty E21 E1 E2 Ty1
IH : forall E Ty E', typeOf [] E Ty -> evalStep E E' * -> typeOf [] E' Ty
Ev : evalStep (app E1 E2) (app E1 E21) @
Ev1 : value E1
Ev2 : evalStep E2 E21 *
Ty : typeOf [] E1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] E2 Ty1
============================
typeOf [] (app E1 E21) Ty
< apply IH to Ty1 Ev2.
Subgoal 2:
Variables: Ty E21 E1 E2 Ty1
IH : forall E Ty E', typeOf [] E Ty -> evalStep E E' * -> typeOf [] E' Ty
Ev : evalStep (app E1 E2) (app E1 E21) @
Ev1 : value E1
Ev2 : evalStep E2 E21 *
Ty : typeOf [] E1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] E2 Ty1
H1 : typeOf [] E21 Ty1
============================
typeOf [] (app E1 E21) Ty
< search.
Subgoal 3:
Variables: Ty E' E2 E1 Ty1 X
IH : forall E Ty E', typeOf [] E Ty -> evalStep E E' * -> typeOf [] E' Ty
Ty : typeOf [] (app (abs X Ty1 E1) E2) Ty
Ev : evalStep (app (abs X Ty1 E1) E2) E' @
Ev1 : value E2
Ev2 : subst X E2 E1 E'
============================
typeOf [] E' Ty
< Ty: case Ty.
Subgoal 3:
Variables: Ty E' E2 E1 Ty1 X Ty2
IH : forall E Ty E', typeOf [] E Ty -> evalStep E E' * -> typeOf [] E' Ty
Ev : evalStep (app (abs X Ty1 E1) E2) E' @
Ev1 : value E2
Ev2 : subst X E2 E1 E'
Ty : typeOf [] (abs X Ty1 E1) (arrowTy Ty2 Ty)
Ty1 : typeOf [] E2 Ty2
============================
typeOf [] E' Ty
< Ty: case Ty.
Subgoal 3:
Variables: Ty E' E2 E1 X Ty2
IH : forall E Ty E', typeOf [] E Ty -> evalStep E E' * -> typeOf [] E' Ty
Ev : evalStep (app (abs X Ty2 E1) E2) E' @
Ev1 : value E2
Ev2 : subst X E2 E1 E'
Ty1 : typeOf [] E2 Ty2
Ty : typeOf [(X, Ty2)] E1 Ty
============================
typeOf [] E' Ty
< apply subst_preservation to Ty Ev2 Ty1.
Subgoal 3:
Variables: Ty E' E2 E1 X Ty2
IH : forall E Ty E', typeOf [] E Ty -> evalStep E E' * -> typeOf [] E' Ty
Ev : evalStep (app (abs X Ty2 E1) E2) E' @
Ev1 : value E2
Ev2 : subst X E2 E1 E'
Ty1 : typeOf [] E2 Ty2
Ty : typeOf [(X, Ty2)] E1 Ty
H1 : typeOf [] E' Ty
============================
typeOf [] E' Ty
< search.
Proof completed.
< Prove mtc:shared_declarations:canonical_form.
Subgoal 1:
Variables: Ty E Ty1 X
IH : forall V Ty, value V * -> typeOf [] V Ty -> canon Ty V
V : value (abs X Ty1 E) @
Ty : typeOf [] (abs X Ty1 E) Ty
============================
canon Ty (abs X Ty1 E)
< case Ty.
Subgoal 1:
Variables: E Ty1 X Ty3
IH : forall V Ty, value V * -> typeOf [] V Ty -> canon Ty V
V : value (abs X Ty1 E) @
H1 : typeOf [(X, Ty1)] E Ty3
============================
canon (arrowTy Ty1 Ty3) (abs X Ty1 E)
< search.
Proof completed.
< Prove mtc:shared_declarations:subst_is.
Subgoal 1:
Variables: X R E1 Ty
IH : forall X R E E', is_e E -> is_e R -> subst X R E E' * -> is_e E'
IsE : is_e (abs X Ty E1)
IsR : is_e R
S : subst X R (abs X Ty E1) (abs X Ty E1) @
============================
is_e (abs X Ty E1)
< search.
Subgoal 2:
Variables: X R E2 Ty Y E1
IH : forall X R E E', is_e E -> is_e R -> subst X R E E' * -> is_e E'
IsE : is_e (abs Y Ty E1)
IsR : is_e R
S : subst X R (abs Y Ty E1) (abs Y Ty E2) @
S1 : X = Y -> false
S2 : subst X R E1 E2 *
============================
is_e (abs Y Ty E2)
< Is: case IsE.
Subgoal 2:
Variables: X R E2 Ty Y E1
IH : forall X R E E', is_e E -> is_e R -> subst X R E E' * -> is_e E'
IsR : is_e R
S : subst X R (abs Y Ty E1) (abs Y Ty E2) @
S1 : X = Y -> false
S2 : subst X R E1 E2 *
Is : is_string Y
Is1 : is_ty Ty
Is2 : is_e E1
============================
is_e (abs Y Ty E2)
< apply IH to _ _ S2.
Subgoal 2:
Variables: X R E2 Ty Y E1
IH : forall X R E E', is_e E -> is_e R -> subst X R E E' * -> is_e E'
IsR : is_e R
S : subst X R (abs Y Ty E1) (abs Y Ty E2) @
S1 : X = Y -> false
S2 : subst X R E1 E2 *
Is : is_string Y
Is1 : is_ty Ty
Is2 : is_e E1
H1 : is_e E2
============================
is_e (abs Y Ty E2)
< search.
Subgoal 3:
Variables: X R E21 E11 E2 E1
IH : forall X R E E', is_e E -> is_e R -> subst X R E E' * -> is_e E'
IsE : is_e (app E1 E2)
IsR : is_e R
S : subst X R (app E1 E2) (app E11 E21) @
S1 : subst X R E1 E11 *
S2 : subst X R E2 E21 *
============================
is_e (app E11 E21)
< case IsE.
Subgoal 3:
Variables: X R E21 E11 E2 E1
IH : forall X R E E', is_e E -> is_e R -> subst X R E E' * -> is_e E'
IsR : is_e R
S : subst X R (app E1 E2) (app E11 E21) @
S1 : subst X R E1 E11 *
S2 : subst X R E2 E21 *
H1 : is_e E1
H2 : is_e E2
============================
is_e (app E11 E21)
< apply IH to _ _ S1.
Subgoal 3:
Variables: X R E21 E11 E2 E1
IH : forall X R E E', is_e E -> is_e R -> subst X R E E' * -> is_e E'
IsR : is_e R
S : subst X R (app E1 E2) (app E11 E21) @
S1 : subst X R E1 E11 *
S2 : subst X R E2 E21 *
H1 : is_e E1
H2 : is_e E2
H3 : is_e E11
============================
is_e (app E11 E21)
< apply IH to _ _ S2.
Subgoal 3:
Variables: X R E21 E11 E2 E1
IH : forall X R E E', is_e E -> is_e R -> subst X R E E' * -> is_e E'
IsR : is_e R
S : subst X R (app E1 E2) (app E11 E21) @
S1 : subst X R E1 E11 *
S2 : subst X R E2 E21 *
H1 : is_e E1
H2 : is_e E2
H3 : is_e E11
H4 : is_e E21
============================
is_e (app E11 E21)
< search.
Subgoal 4:
Variables: X E'
IH : forall X R E E', is_e E -> is_e R -> subst X R E E' * -> is_e E'
IsE : is_e (var X)
IsR : is_e E'
S : subst X E' (var X) E' @
============================
is_e E'
< search.
Subgoal 5:
Variables: X R Y
IH : forall X R E E', is_e E -> is_e R -> subst X R E E' * -> is_e E'
IsE : is_e (var Y)
IsR : is_e R
S : subst X R (var Y) (var Y) @
S1 : X = Y -> false
============================
is_e (var Y)
< search.
Proof completed.
< Prove mtc:shared_declarations:evalStep_is.
Subgoal 1:
Variables: E2 E11 E1
IH : forall E E', is_e E -> evalStep E E' * -> is_e E'
IsE : is_e (app E1 E2)
Ev : evalStep (app E1 E2) (app E11 E2) @
Ev1 : evalStep E1 E11 *
============================
is_e (app E11 E2)
< case IsE.
Subgoal 1:
Variables: E2 E11 E1
IH : forall E E', is_e E -> evalStep E E' * -> is_e E'
Ev : evalStep (app E1 E2) (app E11 E2) @
Ev1 : evalStep E1 E11 *
H1 : is_e E1
H2 : is_e E2
============================
is_e (app E11 E2)
< apply IH to _ Ev1.
Subgoal 1:
Variables: E2 E11 E1
IH : forall E E', is_e E -> evalStep E E' * -> is_e E'
Ev : evalStep (app E1 E2) (app E11 E2) @
Ev1 : evalStep E1 E11 *
H1 : is_e E1
H2 : is_e E2
H3 : is_e E11
============================
is_e (app E11 E2)
< search.
Subgoal 2:
Variables: E21 E1 E2
IH : forall E E', is_e E -> evalStep E E' * -> is_e E'
IsE : is_e (app E1 E2)
Ev : evalStep (app E1 E2) (app E1 E21) @
Ev1 : value E1
Ev2 : evalStep E2 E21 *
============================
is_e (app E1 E21)
< case IsE.
Subgoal 2:
Variables: E21 E1 E2
IH : forall E E', is_e E -> evalStep E E' * -> is_e E'
Ev : evalStep (app E1 E2) (app E1 E21) @
Ev1 : value E1
Ev2 : evalStep E2 E21 *
H1 : is_e E1
H2 : is_e E2
============================
is_e (app E1 E21)
< apply IH to _ Ev2.
Subgoal 2:
Variables: E21 E1 E2
IH : forall E E', is_e E -> evalStep E E' * -> is_e E'
Ev : evalStep (app E1 E2) (app E1 E21) @
Ev1 : value E1
Ev2 : evalStep E2 E21 *
H1 : is_e E1
H2 : is_e E2
H3 : is_e E21
============================
is_e (app E1 E21)
< search.
Subgoal 3:
Variables: E' E2 E1 Ty X
IH : forall E E', is_e E -> evalStep E E' * -> is_e E'
IsE : is_e (app (abs X Ty E1) E2)
Ev : evalStep (app (abs X Ty E1) E2) E' @
Ev1 : value E2
Ev2 : subst X E2 E1 E'
============================
is_e E'
< Is: case IsE.
Subgoal 3:
Variables: E' E2 E1 Ty X
IH : forall E E', is_e E -> evalStep E E' * -> is_e E'
Ev : evalStep (app (abs X Ty E1) E2) E' @
Ev1 : value E2
Ev2 : subst X E2 E1 E'
Is : is_e (abs X Ty E1)
Is1 : is_e E2
============================
is_e E'
< case Is.
Subgoal 3:
Variables: E' E2 E1 Ty X
IH : forall E E', is_e E -> evalStep E E' * -> is_e E'
Ev : evalStep (app (abs X Ty E1) E2) E' @
Ev1 : value E2
Ev2 : subst X E2 E1 E'
Is1 : is_e E2
H1 : is_string X
H2 : is_ty Ty
H3 : is_e E1
============================
is_e E'
< apply subst_is to _ _ Ev2.
Subgoal 3:
Variables: E' E2 E1 Ty X
IH : forall E E', is_e E -> evalStep E E' * -> is_e E'
Ev : evalStep (app (abs X Ty E1) E2) E' @
Ev1 : value E2
Ev2 : subst X E2 E1 E'
Is1 : is_e E2
H1 : is_string X
H2 : is_ty Ty
H3 : is_e E1
H4 : is_e E'
============================
is_e E'
< search.
Proof completed.
< Prove mtc:shared_declarations:subst_total.
Subgoal 2:
Variables: X R E1 Ty S
IH : forall X R E,
is_e E * -> is_string X -> is_e R -> exists E', subst X R E E'
IsE : is_e (abs S Ty E1) @
IsX : is_string X
IsR : is_e R
IsE1 : is_string S
IsE2 : is_ty Ty
IsE3 : is_e E1 *
============================
exists E', subst X R (abs S Ty E1) E'
< Or: apply is_string_eq_or_not to IsX IsE1.
Subgoal 2:
Variables: X R E1 Ty S
IH : forall X R E,
is_e E * -> is_string X -> is_e R -> exists E', subst X R E E'
IsE : is_e (abs S Ty E1) @
IsX : is_string X
IsR : is_e R
IsE1 : is_string S
IsE2 : is_ty Ty
IsE3 : is_e E1 *
Or : X = S \/ (X = S -> false)
============================
exists E', subst X R (abs S Ty E1) E'
< case Or.
Subgoal 2.1:
Variables: R E1 Ty S
IH : forall X R E,
is_e E * -> is_string X -> is_e R -> exists E', subst X R E E'
IsE : is_e (abs S Ty E1) @
IsX : is_string S
IsR : is_e R
IsE1 : is_string S
IsE2 : is_ty Ty
IsE3 : is_e E1 *
============================
exists E', subst S R (abs S Ty E1) E'
< search.
Subgoal 2.2:
Variables: X R E1 Ty S
IH : forall X R E,
is_e E * -> is_string X -> is_e R -> exists E', subst X R E E'
IsE : is_e (abs S Ty E1) @
IsX : is_string X
IsR : is_e R
IsE1 : is_string S
IsE2 : is_ty Ty
IsE3 : is_e E1 *
H1 : X = S -> false
============================
exists E', subst X R (abs S Ty E1) E'
< apply IH to IsE3 IsX IsR.
Subgoal 2.2:
Variables: X R E1 Ty S E'
IH : forall X R E,
is_e E * -> is_string X -> is_e R -> exists E', subst X R E E'
IsE : is_e (abs S Ty E1) @
IsX : is_string X
IsR : is_e R
IsE1 : is_string S
IsE2 : is_ty Ty
IsE3 : is_e E1 *
H1 : X = S -> false
H2 : subst X R E1 E'
============================
exists E', subst X R (abs S Ty E1) E'
< search.
Subgoal 3:
Variables: X R E2 E1
IH : forall X R E,
is_e E * -> is_string X -> is_e R -> exists E', subst X R E E'
IsE : is_e (app E1 E2) @
IsX : is_string X
IsR : is_e R
IsE1 : is_e E1 *
IsE2 : is_e E2 *
============================
exists E', subst X R (app E1 E2) E'
< apply IH to IsE1 IsX IsR.
Subgoal 3:
Variables: X R E2 E1 E'
IH : forall X R E,
is_e E * -> is_string X -> is_e R -> exists E', subst X R E E'
IsE : is_e (app E1 E2) @
IsX : is_string X
IsR : is_e R
IsE1 : is_e E1 *
IsE2 : is_e E2 *
H1 : subst X R E1 E'
============================
exists E', subst X R (app E1 E2) E'
< apply IH to IsE2 IsX IsR.
Subgoal 3:
Variables: X R E2 E1 E' E'1
IH : forall X R E,
is_e E * -> is_string X -> is_e R -> exists E', subst X R E E'
IsE : is_e (app E1 E2) @
IsX : is_string X
IsR : is_e R
IsE1 : is_e E1 *
IsE2 : is_e E2 *
H1 : subst X R E1 E'
H2 : subst X R E2 E'1
============================
exists E', subst X R (app E1 E2) E'
< search.
Subgoal 4:
Variables: X R S
IH : forall X R E,
is_e E * -> is_string X -> is_e R -> exists E', subst X R E E'
IsE : is_e (var S) @
IsX : is_string X
IsR : is_e R
IsE1 : is_string S
============================
exists E', subst X R (var S) E'
< Or: apply is_string_eq_or_not to IsX IsE1.
Subgoal 4:
Variables: X R S
IH : forall X R E,
is_e E * -> is_string X -> is_e R -> exists E', subst X R E E'
IsE : is_e (var S) @
IsX : is_string X
IsR : is_e R
IsE1 : is_string S
Or : X = S \/ (X = S -> false)
============================
exists E', subst X R (var S) E'
< case Or.
Subgoal 4.1:
Variables: R S
IH : forall X R E,
is_e E * -> is_string X -> is_e R -> exists E', subst X R E E'
IsE : is_e (var S) @
IsX : is_string S
IsR : is_e R
IsE1 : is_string S
============================
exists E', subst S R (var S) E'
< search.
Subgoal 4.2:
Variables: X R S
IH : forall X R E,
is_e E * -> is_string X -> is_e R -> exists E', subst X R E E'
IsE : is_e (var S) @
IsX : is_string X
IsR : is_e R
IsE1 : is_string S
H1 : X = S -> false
============================
exists E', subst X R (var S) E'
< search.
Proof completed.
< Prove mtc:shared_declarations:progress.
Subgoal 1:
Variables: Ty2 Ty1 E1 X
IH : forall E Ty,
is_e E -> typeOf [] E Ty * -> value E \/ (exists E', evalStep E E')
IsE : is_e (abs X Ty1 E1)
Ty : typeOf [] (abs X Ty1 E1) (arrowTy Ty1 Ty2) @
Ty1 : typeOf [(X, Ty1)] E1 Ty2 *
============================
value (abs X Ty1 E1) \/ (exists E', evalStep (abs X Ty1 E1) E')
< search.
Subgoal 2:
Variables: Ty Ty1 E2 E1
IH : forall E Ty,
is_e E -> typeOf [] E Ty * -> value E \/ (exists E', evalStep E E')
IsE : is_e (app E1 E2)
Ty : typeOf [] (app E1 E2) Ty @
Ty1 : typeOf [] E1 (arrowTy Ty1 Ty) *
Ty2 : typeOf [] E2 Ty1 *
============================
value (app E1 E2) \/ (exists E', evalStep (app E1 E2) E')
< Is: case IsE.
Subgoal 2:
Variables: Ty Ty1 E2 E1
IH : forall E Ty,
is_e E -> typeOf [] E Ty * -> value E \/ (exists E', evalStep E E')
Ty : typeOf [] (app E1 E2) Ty @
Ty1 : typeOf [] E1 (arrowTy Ty1 Ty) *
Ty2 : typeOf [] E2 Ty1 *
Is : is_e E1
Is1 : is_e E2
============================
value (app E1 E2) \/ (exists E', evalStep (app E1 E2) E')
< Or1: apply IH to _ Ty1.
Subgoal 2:
Variables: Ty Ty1 E2 E1
IH : forall E Ty,
is_e E -> typeOf [] E Ty * -> value E \/ (exists E', evalStep E E')
Ty : typeOf [] (app E1 E2) Ty @
Ty1 : typeOf [] E1 (arrowTy Ty1 Ty) *
Ty2 : typeOf [] E2 Ty1 *
Is : is_e E1
Is1 : is_e E2
Or1 : value E1 \/ (exists E', evalStep E1 E')
============================
value (app E1 E2) \/ (exists E', evalStep (app E1 E2) E')
< Or2: apply IH to _ Ty2.
Subgoal 2:
Variables: Ty Ty1 E2 E1
IH : forall E Ty,
is_e E -> typeOf [] E Ty * -> value E \/ (exists E', evalStep E E')
Ty : typeOf [] (app E1 E2) Ty @
Ty1 : typeOf [] E1 (arrowTy Ty1 Ty) *
Ty2 : typeOf [] E2 Ty1 *
Is : is_e E1
Is1 : is_e E2
Or1 : value E1 \/ (exists E', evalStep E1 E')
Or2 : value E2 \/ (exists E', evalStep E2 E')
============================
value (app E1 E2) \/ (exists E', evalStep (app E1 E2) E')
< Ev1: case Or1.
Subgoal 2.1:
Variables: Ty Ty1 E2 E1
IH : forall E Ty,
is_e E -> typeOf [] E Ty * -> value E \/ (exists E', evalStep E E')
Ty : typeOf [] (app E1 E2) Ty @
Ty1 : typeOf [] E1 (arrowTy Ty1 Ty) *
Ty2 : typeOf [] E2 Ty1 *
Is : is_e E1
Is1 : is_e E2
Or2 : value E2 \/ (exists E', evalStep E2 E')
Ev1 : value E1
============================
value (app E1 E2) \/ (exists E', evalStep (app E1 E2) E')
< Ev2: case Or2.
Subgoal 2.1.1:
Variables: Ty Ty1 E2 E1
IH : forall E Ty,
is_e E -> typeOf [] E Ty * -> value E \/ (exists E', evalStep E E')
Ty : typeOf [] (app E1 E2) Ty @
Ty1 : typeOf [] E1 (arrowTy Ty1 Ty) *
Ty2 : typeOf [] E2 Ty1 *
Is : is_e E1
Is1 : is_e E2
Ev1 : value E1
Ev2 : value E2
============================
value (app E1 E2) \/ (exists E', evalStep (app E1 E2) E')
< C: apply canonical_form to Ev1 Ty1.
Subgoal 2.1.1:
Variables: Ty Ty1 E2 E1
IH : forall E Ty,
is_e E -> typeOf [] E Ty * -> value E \/ (exists E', evalStep E E')
Ty : typeOf [] (app E1 E2) Ty @
Ty1 : typeOf [] E1 (arrowTy Ty1 Ty) *
Ty2 : typeOf [] E2 Ty1 *
Is : is_e E1
Is1 : is_e E2
Ev1 : value E1
Ev2 : value E2
C : canon (arrowTy Ty1 Ty) E1
============================
value (app E1 E2) \/ (exists E', evalStep (app E1 E2) E')
< case C.
Subgoal 2.1.1:
Variables: Ty Ty1 E2 E3 X
IH : forall E Ty,
is_e E -> typeOf [] E Ty * -> value E \/ (exists E', evalStep E E')
Ty : typeOf [] (app (abs X Ty1 E3) E2) Ty @
Ty1 : typeOf [] (abs X Ty1 E3) (arrowTy Ty1 Ty) *
Ty2 : typeOf [] E2 Ty1 *
Is : is_e (abs X Ty1 E3)
Is1 : is_e E2
Ev1 : value (abs X Ty1 E3)
Ev2 : value E2
============================
value (app (abs X Ty1 E3) E2) \/
(exists E', evalStep (app (abs X Ty1 E3) E2) E')
< IsAbs: case Is.
Subgoal 2.1.1:
Variables: Ty Ty1 E2 E3 X
IH : forall E Ty,
is_e E -> typeOf [] E Ty * -> value E \/ (exists E', evalStep E E')
Ty : typeOf [] (app (abs X Ty1 E3) E2) Ty @
Ty1 : typeOf [] (abs X Ty1 E3) (arrowTy Ty1 Ty) *
Ty2 : typeOf [] E2 Ty1 *
Is1 : is_e E2
Ev1 : value (abs X Ty1 E3)
Ev2 : value E2
IsAbs : is_string X
IsAbs1 : is_ty Ty1
IsAbs2 : is_e E3
============================
value (app (abs X Ty1 E3) E2) \/
(exists E', evalStep (app (abs X Ty1 E3) E2) E')
< apply subst_total to IsAbs2 IsAbs Is1.
Subgoal 2.1.1:
Variables: Ty Ty1 E2 E3 X E'
IH : forall E Ty,
is_e E -> typeOf [] E Ty * -> value E \/ (exists E', evalStep E E')
Ty : typeOf [] (app (abs X Ty1 E3) E2) Ty @
Ty1 : typeOf [] (abs X Ty1 E3) (arrowTy Ty1 Ty) *
Ty2 : typeOf [] E2 Ty1 *
Is1 : is_e E2
Ev1 : value (abs X Ty1 E3)
Ev2 : value E2
IsAbs : is_string X
IsAbs1 : is_ty Ty1
IsAbs2 : is_e E3
H1 : subst X E2 E3 E'
============================
value (app (abs X Ty1 E3) E2) \/
(exists E', evalStep (app (abs X Ty1 E3) E2) E')
< search.
Subgoal 2.1.2:
Variables: Ty Ty1 E2 E1 E'
IH : forall E Ty,
is_e E -> typeOf [] E Ty * -> value E \/ (exists E', evalStep E E')
Ty : typeOf [] (app E1 E2) Ty @
Ty1 : typeOf [] E1 (arrowTy Ty1 Ty) *
Ty2 : typeOf [] E2 Ty1 *
Is : is_e E1
Is1 : is_e E2
Ev1 : value E1
Ev2 : evalStep E2 E'
============================
value (app E1 E2) \/ (exists E', evalStep (app E1 E2) E')
< search.
Subgoal 2.2:
Variables: Ty Ty1 E2 E1 E'
IH : forall E Ty,
is_e E -> typeOf [] E Ty * -> value E \/ (exists E', evalStep E E')
Ty : typeOf [] (app E1 E2) Ty @
Ty1 : typeOf [] E1 (arrowTy Ty1 Ty) *
Ty2 : typeOf [] E2 Ty1 *
Is : is_e E1
Is1 : is_e E2
Or2 : value E2 \/ (exists E', evalStep E2 E')
Ev1 : evalStep E1 E'
============================
value (app E1 E2) \/ (exists E', evalStep (app E1 E2) E')
< search.
Subgoal 3:
Variables: Ty X
IH : forall E Ty,
is_e E -> typeOf [] E Ty * -> value E \/ (exists E', evalStep E E')
IsE : is_e (var X)
Ty : typeOf [] (var X) Ty @
Ty1 : lookup [] X Ty
============================
value (var X) \/ (exists E', evalStep (var X) E')
< case Ty1.
Proof completed.