< Module soundX:host.
< Theorem lookup_ty_is :
forall Ctx X Ty,
is_list (is_pair is_string is_ty) Ctx -> lookup Ctx X Ty -> is_ty Ty.
============================
forall Ctx X Ty,
is_list (is_pair is_string is_ty) Ctx -> lookup Ctx X Ty -> is_ty Ty
< induction on 2.
IH : forall Ctx X Ty,
is_list (is_pair is_string is_ty) Ctx -> lookup Ctx X Ty * -> is_ty Ty
============================
forall Ctx X Ty,
is_list (is_pair is_string is_ty) Ctx -> lookup Ctx X Ty @ -> is_ty Ty
< intros Is L.
Variables: Ctx X Ty
IH : forall Ctx X Ty,
is_list (is_pair is_string is_ty) Ctx -> lookup Ctx X Ty * -> is_ty Ty
Is : is_list (is_pair is_string is_ty) Ctx
L : lookup Ctx X Ty @
============================
is_ty Ty
< L: case L.
Subgoal 1:
Variables: X Ty Rest
IH : forall Ctx X Ty,
is_list (is_pair is_string is_ty) Ctx -> lookup Ctx X Ty * -> is_ty Ty
Is : is_list (is_pair is_string is_ty) ((X, Ty)::Rest)
============================
is_ty Ty
< Is: case Is.
Subgoal 1:
Variables: X Ty Rest
IH : forall Ctx X Ty,
is_list (is_pair is_string is_ty) Ctx -> lookup Ctx X Ty * -> is_ty Ty
Is : is_pair is_string is_ty (X, Ty)
Is1 : is_list (is_pair is_string is_ty) Rest
============================
is_ty Ty
< case Is.
Subgoal 1:
Variables: X Ty Rest
IH : forall Ctx X Ty,
is_list (is_pair is_string is_ty) Ctx -> lookup Ctx X Ty * -> is_ty Ty
Is1 : is_list (is_pair is_string is_ty) Rest
H1 : is_string X
H2 : is_ty Ty
============================
is_ty Ty
< search.
Subgoal 2:
Variables: X Ty Rest V K
IH : forall Ctx X Ty,
is_list (is_pair is_string is_ty) Ctx -> lookup Ctx X Ty * -> is_ty Ty
Is : is_list (is_pair is_string is_ty) ((K, V)::Rest)
L : K = X -> false
L1 : lookup Rest X Ty *
============================
is_ty Ty
< Is: case Is.
Subgoal 2:
Variables: X Ty Rest V K
IH : forall Ctx X Ty,
is_list (is_pair is_string is_ty) Ctx -> lookup Ctx X Ty * -> is_ty Ty
L : K = X -> false
L1 : lookup Rest X Ty *
Is : is_pair is_string is_ty (K, V)
Is1 : is_list (is_pair is_string is_ty) Rest
============================
is_ty Ty
< apply IH to _ L1.
Subgoal 2:
Variables: X Ty Rest V K
IH : forall Ctx X Ty,
is_list (is_pair is_string is_ty) Ctx -> lookup Ctx X Ty * -> is_ty Ty
L : K = X -> false
L1 : lookup Rest X Ty *
Is : is_pair is_string is_ty (K, V)
Is1 : is_list (is_pair is_string is_ty) Rest
H1 : is_ty Ty
============================
is_ty Ty
< search.
Proof completed.
< Projection_Constraint proj_ty_is :
forall Ty Ty',
Proj : |{ty}- Ty ~~> Ty' ->
IsTy : is_ty Ty ->
is_ty Ty'.
Proof completed.
< Extensible_Theorem
type_is : forall Ctx T Ty,
IsCtx : is_list (is_pair is_string is_ty) Ctx ->
IsT : is_tm T ->
Ty : typeOf Ctx T Ty ->
is_ty Ty
on Ty.
Subgoal 1:
Variables: Ctx Ty X
IH : forall Ctx T Ty,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T Ty * -> is_ty Ty
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (var X)
Ty : typeOf Ctx (var X) Ty @
Ty1 : lookup Ctx X Ty
============================
is_ty Ty
< apply lookup_ty_is to _ Ty1.
Subgoal 1:
Variables: Ctx Ty X
IH : forall Ctx T Ty,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T Ty * -> is_ty Ty
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (var X)
Ty : typeOf Ctx (var X) Ty @
Ty1 : lookup Ctx X Ty
H1 : is_ty Ty
============================
is_ty Ty
< search.
Subgoal 2:
Variables: Ctx Ty2 Ty1 Body X
IH : forall Ctx T Ty,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T Ty * -> is_ty Ty
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (abs X Ty1 Body)
Ty : typeOf Ctx (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
Ty1 : typeOf ((X, Ty1)::Ctx) Body Ty2 *
============================
is_ty (arrowTy Ty1 Ty2)
< Is: case IsT.
Subgoal 2:
Variables: Ctx Ty2 Ty1 Body X
IH : forall Ctx T Ty,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T Ty * -> is_ty Ty
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
Ty1 : typeOf ((X, Ty1)::Ctx) Body Ty2 *
Is : is_string X
Is1 : is_ty Ty1
Is2 : is_tm Body
============================
is_ty (arrowTy Ty1 Ty2)
< apply IH to _ _ Ty1.
Subgoal 2:
Variables: Ctx Ty2 Ty1 Body X
IH : forall Ctx T Ty,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T Ty * -> is_ty Ty
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
Ty1 : typeOf ((X, Ty1)::Ctx) Body Ty2 *
Is : is_string X
Is1 : is_ty Ty1
Is2 : is_tm Body
H1 : is_ty Ty2
============================
is_ty (arrowTy Ty1 Ty2)
< search.
Subgoal 3:
Variables: Ctx Ty Ty1 T2 T1
IH : forall Ctx T Ty,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T Ty * -> is_ty Ty
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (app T1 T2)
Ty : typeOf Ctx (app T1 T2) Ty @
Ty1 : typeOf Ctx T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx T2 Ty1 *
============================
is_ty Ty
< Is: case IsT.
Subgoal 3:
Variables: Ctx Ty Ty1 T2 T1
IH : forall Ctx T Ty,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T Ty * -> is_ty Ty
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (app T1 T2) Ty @
Ty1 : typeOf Ctx T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx T2 Ty1 *
Is : is_tm T1
Is1 : is_tm T2
============================
is_ty Ty
< IsTy: apply IH to _ _ Ty1.
Subgoal 3:
Variables: Ctx Ty Ty1 T2 T1
IH : forall Ctx T Ty,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T Ty * -> is_ty Ty
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (app T1 T2) Ty @
Ty1 : typeOf Ctx T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx T2 Ty1 *
Is : is_tm T1
Is1 : is_tm T2
IsTy : is_ty (arrowTy Ty1 Ty)
============================
is_ty Ty
< case IsTy.
Subgoal 3:
Variables: Ctx Ty Ty1 T2 T1
IH : forall Ctx T Ty,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T Ty * -> is_ty Ty
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (app T1 T2) Ty @
Ty1 : typeOf Ctx T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx T2 Ty1 *
Is : is_tm T1
Is1 : is_tm T2
H1 : is_ty Ty1
H2 : is_ty Ty
============================
is_ty Ty
< search.
Subgoal 4:
Variables: Ctx I
IH : forall Ctx T Ty,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T Ty * -> is_ty Ty
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (num I)
Ty : typeOf Ctx (num I) intTy @
============================
is_ty intTy
< search.
Subgoal 5:
Variables: Ctx T2 T1
IH : forall Ctx T Ty,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T Ty * -> is_ty Ty
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (plus T1 T2)
Ty : typeOf Ctx (plus T1 T2) intTy @
Ty1 : typeOf Ctx T1 intTy *
Ty2 : typeOf Ctx T2 intTy *
============================
is_ty intTy
< search.
Proof completed.
< Projection_Constraint proj_is :
forall Ctx T T',
Proj : Ctx |{tm}- T ~~> T' ->
IsCtx : is_list (is_pair is_string is_ty) Ctx ->
IsT : is_tm T ->
is_tm T'.
Proof completed.
< Extensible_Theorem
type_unique : forall Ctx T TyA TyB,
IsCtx : is_list (is_pair is_string is_ty) Ctx ->
IsT : is_tm T ->
TyA : typeOf Ctx T TyA ->
TyB : typeOf Ctx T TyB ->
TyA = TyB
on TyA.
Subgoal 1:
Variables: Ctx TyA TyB X
IH : forall Ctx T TyA TyB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (var X)
TyA : typeOf Ctx (var X) TyA @
TyB : typeOf Ctx (var X) TyB
TyA1 : lookup Ctx X TyA
============================
TyA = TyB
< TyB: case TyB.
Subgoal 1:
Variables: Ctx TyA TyB X
IH : forall Ctx T TyA TyB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (var X)
TyA : typeOf Ctx (var X) TyA @
TyA1 : lookup Ctx X TyA
TyB : lookup Ctx X TyB
============================
TyA = TyB
< apply lookup_unique to TyA1 TyB.
Subgoal 1:
Variables: Ctx TyB X
IH : forall Ctx T TyA TyB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (var X)
TyA : typeOf Ctx (var X) TyB @
TyA1 : lookup Ctx X TyB
TyB : lookup Ctx X TyB
============================
TyB = TyB
< search.
Subgoal 2:
Variables: Ctx TyB Ty2 Ty1 Body X
IH : forall Ctx T TyA TyB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (abs X Ty1 Body)
TyA : typeOf Ctx (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
TyB : typeOf Ctx (abs X Ty1 Body) TyB
TyA1 : typeOf ((X, Ty1)::Ctx) Body Ty2 *
============================
arrowTy Ty1 Ty2 = TyB
< case IsT.
Subgoal 2:
Variables: Ctx TyB Ty2 Ty1 Body X
IH : forall Ctx T TyA TyB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
TyA : typeOf Ctx (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
TyB : typeOf Ctx (abs X Ty1 Body) TyB
TyA1 : typeOf ((X, Ty1)::Ctx) Body Ty2 *
H1 : is_string X
H2 : is_ty Ty1
H3 : is_tm Body
============================
arrowTy Ty1 Ty2 = TyB
< TyB: case TyB.
Subgoal 2:
Variables: Ctx Ty2 Ty1 Body X Ty4
IH : forall Ctx T TyA TyB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
TyA : typeOf Ctx (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
TyA1 : typeOf ((X, Ty1)::Ctx) Body Ty2 *
H1 : is_string X
H2 : is_ty Ty1
H3 : is_tm Body
TyB : typeOf ((X, Ty1)::Ctx) Body Ty4
============================
arrowTy Ty1 Ty2 = arrowTy Ty1 Ty4
< apply IH to _ _ TyA1 TyB.
Subgoal 2:
Variables: Ctx Ty1 Body X Ty4
IH : forall Ctx T TyA TyB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
TyA : typeOf Ctx (abs X Ty1 Body) (arrowTy Ty1 Ty4) @
TyA1 : typeOf ((X, Ty1)::Ctx) Body Ty4 *
H1 : is_string X
H2 : is_ty Ty1
H3 : is_tm Body
TyB : typeOf ((X, Ty1)::Ctx) Body Ty4
============================
arrowTy Ty1 Ty4 = arrowTy Ty1 Ty4
< search.
Subgoal 3:
Variables: Ctx TyA TyB Ty1 T2 T1
IH : forall Ctx T TyA TyB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (app T1 T2)
TyA : typeOf Ctx (app T1 T2) TyA @
TyB : typeOf Ctx (app T1 T2) TyB
TyA1 : typeOf Ctx T1 (arrowTy Ty1 TyA) *
TyA2 : typeOf Ctx T2 Ty1 *
============================
TyA = TyB
< case IsT.
Subgoal 3:
Variables: Ctx TyA TyB Ty1 T2 T1
IH : forall Ctx T TyA TyB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
TyA : typeOf Ctx (app T1 T2) TyA @
TyB : typeOf Ctx (app T1 T2) TyB
TyA1 : typeOf Ctx T1 (arrowTy Ty1 TyA) *
TyA2 : typeOf Ctx T2 Ty1 *
H1 : is_tm T1
H2 : is_tm T2
============================
TyA = TyB
< TyB: case TyB.
Subgoal 3:
Variables: Ctx TyA TyB Ty1 T2 T1 Ty2
IH : forall Ctx T TyA TyB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
TyA : typeOf Ctx (app T1 T2) TyA @
TyA1 : typeOf Ctx T1 (arrowTy Ty1 TyA) *
TyA2 : typeOf Ctx T2 Ty1 *
H1 : is_tm T1
H2 : is_tm T2
TyB : typeOf Ctx T1 (arrowTy Ty2 TyB)
TyB1 : typeOf Ctx T2 Ty2
============================
TyA = TyB
< apply IH to _ _ TyA1 TyB.
Subgoal 3:
Variables: Ctx TyB T2 T1 Ty2
IH : forall Ctx T TyA TyB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
TyA : typeOf Ctx (app T1 T2) TyB @
TyA1 : typeOf Ctx T1 (arrowTy Ty2 TyB) *
TyA2 : typeOf Ctx T2 Ty2 *
H1 : is_tm T1
H2 : is_tm T2
TyB : typeOf Ctx T1 (arrowTy Ty2 TyB)
TyB1 : typeOf Ctx T2 Ty2
============================
TyB = TyB
< apply IH to _ _ TyA2 TyB1.
Subgoal 3:
Variables: Ctx TyB T2 T1 Ty2
IH : forall Ctx T TyA TyB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
TyA : typeOf Ctx (app T1 T2) TyB @
TyA1 : typeOf Ctx T1 (arrowTy Ty2 TyB) *
TyA2 : typeOf Ctx T2 Ty2 *
H1 : is_tm T1
H2 : is_tm T2
TyB : typeOf Ctx T1 (arrowTy Ty2 TyB)
TyB1 : typeOf Ctx T2 Ty2
============================
TyB = TyB
< search.
Subgoal 4:
Variables: Ctx TyB I
IH : forall Ctx T TyA TyB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (num I)
TyA : typeOf Ctx (num I) intTy @
TyB : typeOf Ctx (num I) TyB
============================
intTy = TyB
< case TyB.
Subgoal 4:
Variables: Ctx I
IH : forall Ctx T TyA TyB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (num I)
TyA : typeOf Ctx (num I) intTy @
============================
intTy = intTy
< search.
Subgoal 5:
Variables: Ctx TyB T2 T1
IH : forall Ctx T TyA TyB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (plus T1 T2)
TyA : typeOf Ctx (plus T1 T2) intTy @
TyB : typeOf Ctx (plus T1 T2) TyB
TyA1 : typeOf Ctx T1 intTy *
TyA2 : typeOf Ctx T2 intTy *
============================
intTy = TyB
< case TyB.
Subgoal 5:
Variables: Ctx T2 T1
IH : forall Ctx T TyA TyB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> typeOf Ctx T TyA * ->
typeOf Ctx T TyB -> TyA = TyB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (plus T1 T2)
TyA : typeOf Ctx (plus T1 T2) intTy @
TyA1 : typeOf Ctx T1 intTy *
TyA2 : typeOf Ctx T2 intTy *
H1 : typeOf Ctx T1 intTy
H2 : typeOf Ctx T2 intTy
============================
intTy = intTy
< search.
Proof completed.
< Extensible_Theorem
ty_lookup : forall Ctx1 Ctx2 T Ty,
Ty : typeOf Ctx1 T Ty ->
L : (forall X XTy,
lookup Ctx1 X XTy -> lookup Ctx2 X XTy) ->
typeOf Ctx2 T Ty
on Ty.
Subgoal 1:
Variables: Ctx1 Ctx2 Ty X
IH : forall Ctx1 Ctx2 T Ty,
typeOf Ctx1 T Ty * -> (forall X XTy,
lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (var X) Ty @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : lookup Ctx1 X Ty
============================
typeOf Ctx2 (var X) Ty
< apply L to Ty1.
Subgoal 1:
Variables: Ctx1 Ctx2 Ty X
IH : forall Ctx1 Ctx2 T Ty,
typeOf Ctx1 T Ty * -> (forall X XTy,
lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (var X) Ty @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : lookup Ctx1 X Ty
H1 : lookup Ctx2 X Ty
============================
typeOf Ctx2 (var X) Ty
< search.
Subgoal 2:
Variables: Ctx1 Ctx2 Ty2 Ty1 Body X
IH : forall Ctx1 Ctx2 T Ty,
typeOf Ctx1 T Ty * -> (forall X XTy,
lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf ((X, Ty1)::Ctx1) Body Ty2 *
============================
typeOf Ctx2 (abs X Ty1 Body) (arrowTy Ty1 Ty2)
< apply IH to Ty1 _ with
Ctx2 = (X, Ty1)::Ctx2.
Subgoal 2.1:
Variables: Ctx1 Ctx2 Ty2 Ty1 Body X
IH : forall Ctx1 Ctx2 T Ty,
typeOf Ctx1 T Ty * -> (forall X XTy,
lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf ((X, Ty1)::Ctx1) Body Ty2 *
============================
forall X1 XTy, lookup ((X, Ty1)::Ctx1) X1 XTy -> lookup ((X, Ty1)::Ctx2) X1 XTy
< intros LkpX.
Subgoal 2.1:
Variables: Ctx1 Ctx2 Ty2 Ty1 Body X X1 XTy
IH : forall Ctx1 Ctx2 T Ty,
typeOf Ctx1 T Ty * -> (forall X XTy,
lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf ((X, Ty1)::Ctx1) Body Ty2 *
LkpX : lookup ((X, Ty1)::Ctx1) X1 XTy
============================
lookup ((X, Ty1)::Ctx2) X1 XTy
< LkpX: case LkpX.
Subgoal 2.1.1:
Variables: Ctx1 Ctx2 Ty2 Body X1 XTy
IH : forall Ctx1 Ctx2 T Ty,
typeOf Ctx1 T Ty * -> (forall X XTy,
lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (abs X1 XTy Body) (arrowTy XTy Ty2) @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf ((X1, XTy)::Ctx1) Body Ty2 *
============================
lookup ((X1, XTy)::Ctx2) X1 XTy
< search.
Subgoal 2.1.2:
Variables: Ctx1 Ctx2 Ty2 Ty1 Body X X1 XTy
IH : forall Ctx1 Ctx2 T Ty,
typeOf Ctx1 T Ty * -> (forall X XTy,
lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf ((X, Ty1)::Ctx1) Body Ty2 *
LkpX : X = X1 -> false
LkpX1 : lookup Ctx1 X1 XTy
============================
lookup ((X, Ty1)::Ctx2) X1 XTy
< apply L to LkpX1.
Subgoal 2.1.2:
Variables: Ctx1 Ctx2 Ty2 Ty1 Body X X1 XTy
IH : forall Ctx1 Ctx2 T Ty,
typeOf Ctx1 T Ty * -> (forall X XTy,
lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf ((X, Ty1)::Ctx1) Body Ty2 *
LkpX : X = X1 -> false
LkpX1 : lookup Ctx1 X1 XTy
H1 : lookup Ctx2 X1 XTy
============================
lookup ((X, Ty1)::Ctx2) X1 XTy
< search.
Subgoal 2:
Variables: Ctx1 Ctx2 Ty2 Ty1 Body X
IH : forall Ctx1 Ctx2 T Ty,
typeOf Ctx1 T Ty * -> (forall X XTy,
lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf ((X, Ty1)::Ctx1) Body Ty2 *
H1 : typeOf ((X, Ty1)::Ctx2) Body Ty2
============================
typeOf Ctx2 (abs X Ty1 Body) (arrowTy Ty1 Ty2)
< search.
Subgoal 3:
Variables: Ctx1 Ctx2 Ty Ty1 T2 T1
IH : forall Ctx1 Ctx2 T Ty,
typeOf Ctx1 T Ty * -> (forall X XTy,
lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (app T1 T2) Ty @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf Ctx1 T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx1 T2 Ty1 *
============================
typeOf Ctx2 (app T1 T2) Ty
< apply IH to Ty1 L.
Subgoal 3:
Variables: Ctx1 Ctx2 Ty Ty1 T2 T1
IH : forall Ctx1 Ctx2 T Ty,
typeOf Ctx1 T Ty * -> (forall X XTy,
lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (app T1 T2) Ty @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf Ctx1 T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx1 T2 Ty1 *
H1 : typeOf Ctx2 T1 (arrowTy Ty1 Ty)
============================
typeOf Ctx2 (app T1 T2) Ty
< apply IH to Ty2 L.
Subgoal 3:
Variables: Ctx1 Ctx2 Ty Ty1 T2 T1
IH : forall Ctx1 Ctx2 T Ty,
typeOf Ctx1 T Ty * -> (forall X XTy,
lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (app T1 T2) Ty @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf Ctx1 T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx1 T2 Ty1 *
H1 : typeOf Ctx2 T1 (arrowTy Ty1 Ty)
H2 : typeOf Ctx2 T2 Ty1
============================
typeOf Ctx2 (app T1 T2) Ty
< search.
Subgoal 4:
Variables: Ctx1 Ctx2 I
IH : forall Ctx1 Ctx2 T Ty,
typeOf Ctx1 T Ty * -> (forall X XTy,
lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (num I) intTy @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
============================
typeOf Ctx2 (num I) intTy
< search.
Subgoal 5:
Variables: Ctx1 Ctx2 T2 T1
IH : forall Ctx1 Ctx2 T Ty,
typeOf Ctx1 T Ty * -> (forall X XTy,
lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (plus T1 T2) intTy @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf Ctx1 T1 intTy *
Ty2 : typeOf Ctx1 T2 intTy *
============================
typeOf Ctx2 (plus T1 T2) intTy
< apply IH to Ty1 L.
Subgoal 5:
Variables: Ctx1 Ctx2 T2 T1
IH : forall Ctx1 Ctx2 T Ty,
typeOf Ctx1 T Ty * -> (forall X XTy,
lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (plus T1 T2) intTy @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf Ctx1 T1 intTy *
Ty2 : typeOf Ctx1 T2 intTy *
H1 : typeOf Ctx2 T1 intTy
============================
typeOf Ctx2 (plus T1 T2) intTy
< apply IH to Ty2 L.
Subgoal 5:
Variables: Ctx1 Ctx2 T2 T1
IH : forall Ctx1 Ctx2 T Ty,
typeOf Ctx1 T Ty * -> (forall X XTy,
lookup Ctx1 X XTy -> lookup Ctx2 X XTy) -> typeOf Ctx2 T Ty
Ty : typeOf Ctx1 (plus T1 T2) intTy @
L : forall X XTy, lookup Ctx1 X XTy -> lookup Ctx2 X XTy
Ty1 : typeOf Ctx1 T1 intTy *
Ty2 : typeOf Ctx1 T2 intTy *
H1 : typeOf Ctx2 T1 intTy
H2 : typeOf Ctx2 T2 intTy
============================
typeOf Ctx2 (plus T1 T2) intTy
< search.
Proof completed.
< Theorem empty_ty_any :
forall T Ty Ctx, typeOf [] T Ty -> typeOf Ctx T Ty.
============================
forall T Ty Ctx, typeOf [] T Ty -> typeOf Ctx T Ty
< intros T.
Variables: T Ty Ctx
T : typeOf [] T Ty
============================
typeOf Ctx T Ty
< backchain ty_lookup.
Variables: T Ty Ctx
T : typeOf [] T Ty
============================
forall X XTy, lookup [] X XTy -> lookup Ctx X XTy
< intros L.
Variables: T Ty Ctx X XTy
T : typeOf [] T Ty
L : lookup [] X XTy
============================
lookup Ctx X XTy
< case L.
Proof completed.
< Projection_Constraint proj_ty_unique :
forall Ty TyA TyB,
|{ty}- Ty ~~> TyA -> |{ty}- Ty ~~> TyB -> is_ty Ty -> TyA = TyB.
Proof completed.
< Projection_Constraint proj_tm_unique :
forall Ctx T TA TB,
Ctx |{tm}- T ~~> TA -> Ctx |{tm}- T ~~> TB -> is_tm T -> is_list (is_pair is_string is_ty) Ctx ->
TA = TB.
Proof completed.
< Theorem lookup_desugar_ctx :
forall Ctx X Ty Ctx',
lookup Ctx X Ty -> desugar_ctx Ctx Ctx' -> exists Ty',
lookup Ctx' X Ty' /\ desugar_ty Ty Ty'.
============================
forall Ctx X Ty Ctx',
lookup Ctx X Ty -> desugar_ctx Ctx Ctx' -> exists Ty',
lookup Ctx' X Ty' /\ desugar_ty Ty Ty'
< induction on 1.
IH : forall Ctx X Ty Ctx',
lookup Ctx X Ty * -> desugar_ctx Ctx Ctx' -> exists Ty',
lookup Ctx' X Ty' /\ desugar_ty Ty Ty'
============================
forall Ctx X Ty Ctx',
lookup Ctx X Ty @ -> desugar_ctx Ctx Ctx' -> exists Ty',
lookup Ctx' X Ty' /\ desugar_ty Ty Ty'
< intros L D.
Variables: Ctx X Ty Ctx'
IH : forall Ctx X Ty Ctx',
lookup Ctx X Ty * -> desugar_ctx Ctx Ctx' -> exists Ty',
lookup Ctx' X Ty' /\ desugar_ty Ty Ty'
L : lookup Ctx X Ty @
D : desugar_ctx Ctx Ctx'
============================
exists Ty', lookup Ctx' X Ty' /\ desugar_ty Ty Ty'
< L: case L.
Subgoal 1:
Variables: X Ty Ctx' Rest
IH : forall Ctx X Ty Ctx',
lookup Ctx X Ty * -> desugar_ctx Ctx Ctx' -> exists Ty',
lookup Ctx' X Ty' /\ desugar_ty Ty Ty'
D : desugar_ctx ((X, Ty)::Rest) Ctx'
============================
exists Ty', lookup Ctx' X Ty' /\ desugar_ty Ty Ty'
< case D.
Subgoal 1:
Variables: X Ty Rest DRest DTy
IH : forall Ctx X Ty Ctx',
lookup Ctx X Ty * -> desugar_ctx Ctx Ctx' -> exists Ty',
lookup Ctx' X Ty' /\ desugar_ty Ty Ty'
H1 : desugar_ty Ty DTy
H2 : desugar_ctx Rest DRest
============================
exists Ty', lookup ((X, DTy)::DRest) X Ty' /\ desugar_ty Ty Ty'
< search.
Subgoal 2:
Variables: X Ty Ctx' Rest V K
IH : forall Ctx X Ty Ctx',
lookup Ctx X Ty * -> desugar_ctx Ctx Ctx' -> exists Ty',
lookup Ctx' X Ty' /\ desugar_ty Ty Ty'
D : desugar_ctx ((K, V)::Rest) Ctx'
L : K = X -> false
L1 : lookup Rest X Ty *
============================
exists Ty', lookup Ctx' X Ty' /\ desugar_ty Ty Ty'
< D: case D.
Subgoal 2:
Variables: X Ty Rest V K DRest DTy
IH : forall Ctx X Ty Ctx',
lookup Ctx X Ty * -> desugar_ctx Ctx Ctx' -> exists Ty',
lookup Ctx' X Ty' /\ desugar_ty Ty Ty'
L : K = X -> false
L1 : lookup Rest X Ty *
D : desugar_ty V DTy
D1 : desugar_ctx Rest DRest
============================
exists Ty', lookup ((K, DTy)::DRest) X Ty' /\ desugar_ty Ty Ty'
< apply IH to L1 D1.
Subgoal 2:
Variables: X Ty Rest V K DRest DTy Ty'
IH : forall Ctx X Ty Ctx',
lookup Ctx X Ty * -> desugar_ctx Ctx Ctx' -> exists Ty',
lookup Ctx' X Ty' /\ desugar_ty Ty Ty'
L : K = X -> false
L1 : lookup Rest X Ty *
D : desugar_ty V DTy
D1 : desugar_ctx Rest DRest
H1 : lookup DRest X Ty'
H2 : desugar_ty Ty Ty'
============================
exists Ty', lookup ((K, DTy)::DRest) X Ty' /\ desugar_ty Ty Ty'
< search.
Proof completed.
< Theorem desugar_ty_unique :
forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA -> desugar_ty Ty TyB -> TyA = TyB.
============================
forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA -> desugar_ty Ty TyB -> TyA = TyB
< induction on 2.
IH : forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA * -> desugar_ty Ty TyB -> TyA = TyB
============================
forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA @ -> desugar_ty Ty TyB -> TyA = TyB
< intros IsTy DA DB.
Variables: Ty TyA TyB
IH : forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA * -> desugar_ty Ty TyB -> TyA = TyB
IsTy : is_ty Ty
DA : desugar_ty Ty TyA @
DB : desugar_ty Ty TyB
============================
TyA = TyB
< DA: case DA.
Subgoal 1:
Variables: TyB DB DA B A
IH : forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA * -> desugar_ty Ty TyB -> TyA = TyB
IsTy : is_ty (arrowTy A B)
DB : desugar_ty (arrowTy A B) TyB
DA : desugar_ty A DA *
DA1 : desugar_ty B DB *
============================
arrowTy DA DB = TyB
< DB: case DB.
Subgoal 1.1:
Variables: DB DA B A DB1 DA1
IH : forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA * -> desugar_ty Ty TyB -> TyA = TyB
IsTy : is_ty (arrowTy A B)
DA : desugar_ty A DA *
DA1 : desugar_ty B DB *
DB : desugar_ty A DA1
DB1 : desugar_ty B DB1
============================
arrowTy DA DB = arrowTy DA1 DB1
< case IsTy.
Subgoal 1.1:
Variables: DB DA B A DB1 DA1
IH : forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA * -> desugar_ty Ty TyB -> TyA = TyB
DA : desugar_ty A DA *
DA1 : desugar_ty B DB *
DB : desugar_ty A DA1
DB1 : desugar_ty B DB1
H1 : is_ty A
H2 : is_ty B
============================
arrowTy DA DB = arrowTy DA1 DB1
< apply IH to _ DA DB.
Subgoal 1.1:
Variables: DB B A DB1 DA1
IH : forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA * -> desugar_ty Ty TyB -> TyA = TyB
DA : desugar_ty A DA1 *
DA1 : desugar_ty B DB *
DB : desugar_ty A DA1
DB1 : desugar_ty B DB1
H1 : is_ty A
H2 : is_ty B
============================
arrowTy DA1 DB = arrowTy DA1 DB1
< apply IH to _ DA1 DB1.
Subgoal 1.1:
Variables: B A DB1 DA1
IH : forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA * -> desugar_ty Ty TyB -> TyA = TyB
DA : desugar_ty A DA1 *
DA1 : desugar_ty B DB1 *
DB : desugar_ty A DA1
DB1 : desugar_ty B DB1
H1 : is_ty A
H2 : is_ty B
============================
arrowTy DA1 DB1 = arrowTy DA1 DB1
< search.
Subgoal 1.2:
Variables: TyB DB DA B A Ty_P
IH : forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA * -> desugar_ty Ty TyB -> TyA = TyB
IsTy : is_ty (arrowTy A B)
DA : desugar_ty A DA *
DA1 : desugar_ty B DB *
DB : |{ty}- arrowTy A B ~~> Ty_P
DB1 : desugar_ty Ty_P TyB
============================
arrowTy DA DB = TyB
< case DB.
Subgoal 2:
Variables: TyB
IH : forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA * -> desugar_ty Ty TyB -> TyA = TyB
IsTy : is_ty intTy
DB : desugar_ty intTy TyB
============================
intTy = TyB
< DB: case DB.
Subgoal 2.1:
IH : forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA * -> desugar_ty Ty TyB -> TyA = TyB
IsTy : is_ty intTy
============================
intTy = intTy
< search.
Subgoal 2.2:
Variables: TyB Ty_P
IH : forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA * -> desugar_ty Ty TyB -> TyA = TyB
IsTy : is_ty intTy
DB : |{ty}- intTy ~~> Ty_P
DB1 : desugar_ty Ty_P TyB
============================
intTy = TyB
< case DB.
Subgoal 3:
Variables: Ty TyA TyB Ty_P
IH : forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA * -> desugar_ty Ty TyB -> TyA = TyB
IsTy : is_ty Ty
DB : desugar_ty Ty TyB
DA : |{ty}- Ty ~~> Ty_P
DA1 : desugar_ty Ty_P TyA *
============================
TyA = TyB
< DB: case DB.
Subgoal 3.1:
Variables: TyA Ty_P DB DA B A
IH : forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA * -> desugar_ty Ty TyB -> TyA = TyB
IsTy : is_ty (arrowTy A B)
DA : |{ty}- arrowTy A B ~~> Ty_P
DA1 : desugar_ty Ty_P TyA *
DB : desugar_ty A DA
DB1 : desugar_ty B DB
============================
TyA = arrowTy DA DB
< case DA.
Subgoal 3.2:
Variables: TyA Ty_P
IH : forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA * -> desugar_ty Ty TyB -> TyA = TyB
IsTy : is_ty intTy
DA : |{ty}- intTy ~~> Ty_P
DA1 : desugar_ty Ty_P TyA *
============================
TyA = intTy
< case DA.
Subgoal 3.3:
Variables: Ty TyA TyB Ty_P Ty_P1
IH : forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA * -> desugar_ty Ty TyB -> TyA = TyB
IsTy : is_ty Ty
DA : |{ty}- Ty ~~> Ty_P
DA1 : desugar_ty Ty_P TyA *
DB : |{ty}- Ty ~~> Ty_P1
DB1 : desugar_ty Ty_P1 TyB
============================
TyA = TyB
< apply proj_ty_unique to DA DB _.
Subgoal 3.3:
Variables: Ty TyA TyB Ty_P1
IH : forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA * -> desugar_ty Ty TyB -> TyA = TyB
IsTy : is_ty Ty
DA : |{ty}- Ty ~~> Ty_P1
DA1 : desugar_ty Ty_P1 TyA *
DB : |{ty}- Ty ~~> Ty_P1
DB1 : desugar_ty Ty_P1 TyB
============================
TyA = TyB
< apply proj_ty_is to DA _.
Subgoal 3.3:
Variables: Ty TyA TyB Ty_P1
IH : forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA * -> desugar_ty Ty TyB -> TyA = TyB
IsTy : is_ty Ty
DA : |{ty}- Ty ~~> Ty_P1
DA1 : desugar_ty Ty_P1 TyA *
DB : |{ty}- Ty ~~> Ty_P1
DB1 : desugar_ty Ty_P1 TyB
H1 : is_ty Ty_P1
============================
TyA = TyB
< apply IH to _ DA1 DB1.
Subgoal 3.3:
Variables: Ty TyB Ty_P1
IH : forall Ty TyA TyB,
is_ty Ty -> desugar_ty Ty TyA * -> desugar_ty Ty TyB -> TyA = TyB
IsTy : is_ty Ty
DA : |{ty}- Ty ~~> Ty_P1
DA1 : desugar_ty Ty_P1 TyB *
DB : |{ty}- Ty ~~> Ty_P1
DB1 : desugar_ty Ty_P1 TyB
H1 : is_ty Ty_P1
============================
TyB = TyB
< search.
Proof completed.
< Theorem desugar_tm_unique :
forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA ->
desugar_tm Ctx T TB -> TA = TB.
============================
forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA -> desugar_tm Ctx T TB ->
TA = TB
< induction on 3.
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
============================
forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA @ -> desugar_tm Ctx T TB ->
TA = TB
< intros IsCtx IsT DA DB.
Variables: Ctx T TA TB
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm T
DA : desugar_tm Ctx T TA @
DB : desugar_tm Ctx T TB
============================
TA = TB
< DA: case DA.
Subgoal 1:
Variables: Ctx TB X
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (var X)
DB : desugar_tm Ctx (var X) TB
============================
var X = TB
< DB: case DB.
Subgoal 1.1:
Variables: Ctx X
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (var X)
============================
var X = var X
< search.
Subgoal 1.2:
Variables: Ctx TB X T_P
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (var X)
DB : Ctx |{tm}- var X ~~> T_P
DB1 : desugar_tm Ctx T_P TB
============================
var X = TB
< case DB.
Subgoal 2:
Variables: Ctx TB DTm DTy X Tm Ty
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (abs X Ty Tm)
DB : desugar_tm Ctx (abs X Ty Tm) TB
DA : desugar_ty Ty DTy
DA1 : desugar_tm ((X, Ty)::Ctx) Tm DTm *
============================
abs X DTy DTm = TB
< DB: case DB.
Subgoal 2.1:
Variables: Ctx DTm DTy X Tm Ty DTm1 DTy1
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (abs X Ty Tm)
DA : desugar_ty Ty DTy
DA1 : desugar_tm ((X, Ty)::Ctx) Tm DTm *
DB : desugar_ty Ty DTy1
DB1 : desugar_tm ((X, Ty)::Ctx) Tm DTm1
============================
abs X DTy DTm = abs X DTy1 DTm1
< case IsT.
Subgoal 2.1:
Variables: Ctx DTm DTy X Tm Ty DTm1 DTy1
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
DA : desugar_ty Ty DTy
DA1 : desugar_tm ((X, Ty)::Ctx) Tm DTm *
DB : desugar_ty Ty DTy1
DB1 : desugar_tm ((X, Ty)::Ctx) Tm DTm1
H1 : is_string X
H2 : is_ty Ty
H3 : is_tm Tm
============================
abs X DTy DTm = abs X DTy1 DTm1
< apply IH to _ _ DA1 DB1.
Subgoal 2.1:
Variables: Ctx DTy X Tm Ty DTm1 DTy1
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
DA : desugar_ty Ty DTy
DA1 : desugar_tm ((X, Ty)::Ctx) Tm DTm1 *
DB : desugar_ty Ty DTy1
DB1 : desugar_tm ((X, Ty)::Ctx) Tm DTm1
H1 : is_string X
H2 : is_ty Ty
H3 : is_tm Tm
============================
abs X DTy DTm1 = abs X DTy1 DTm1
< apply desugar_ty_unique to _ DA DB.
Subgoal 2.1:
Variables: Ctx X Tm Ty DTm1 DTy1
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
DA : desugar_ty Ty DTy1
DA1 : desugar_tm ((X, Ty)::Ctx) Tm DTm1 *
DB : desugar_ty Ty DTy1
DB1 : desugar_tm ((X, Ty)::Ctx) Tm DTm1
H1 : is_string X
H2 : is_ty Ty
H3 : is_tm Tm
============================
abs X DTy1 DTm1 = abs X DTy1 DTm1
< search.
Subgoal 2.2:
Variables: Ctx TB DTm DTy X Tm Ty T_P
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (abs X Ty Tm)
DA : desugar_ty Ty DTy
DA1 : desugar_tm ((X, Ty)::Ctx) Tm DTm *
DB : Ctx |{tm}- abs X Ty Tm ~~> T_P
DB1 : desugar_tm Ctx T_P TB
============================
abs X DTy DTm = TB
< case DB.
Subgoal 3:
Variables: Ctx TB DB DA B A
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (app A B)
DB : desugar_tm Ctx (app A B) TB
DA : desugar_tm Ctx A DA *
DA1 : desugar_tm Ctx B DB *
============================
app DA DB = TB
< DB: case DB.
Subgoal 3.1:
Variables: Ctx DB DA B A DB1 DA1
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (app A B)
DA : desugar_tm Ctx A DA *
DA1 : desugar_tm Ctx B DB *
DB : desugar_tm Ctx A DA1
DB1 : desugar_tm Ctx B DB1
============================
app DA DB = app DA1 DB1
< case IsT.
Subgoal 3.1:
Variables: Ctx DB DA B A DB1 DA1
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
DA : desugar_tm Ctx A DA *
DA1 : desugar_tm Ctx B DB *
DB : desugar_tm Ctx A DA1
DB1 : desugar_tm Ctx B DB1
H1 : is_tm A
H2 : is_tm B
============================
app DA DB = app DA1 DB1
< apply IH to _ _ DA DB.
Subgoal 3.1:
Variables: Ctx DB B A DB1 DA1
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
DA : desugar_tm Ctx A DA1 *
DA1 : desugar_tm Ctx B DB *
DB : desugar_tm Ctx A DA1
DB1 : desugar_tm Ctx B DB1
H1 : is_tm A
H2 : is_tm B
============================
app DA1 DB = app DA1 DB1
< apply IH to _ _ DA1 DB1.
Subgoal 3.1:
Variables: Ctx B A DB1 DA1
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
DA : desugar_tm Ctx A DA1 *
DA1 : desugar_tm Ctx B DB1 *
DB : desugar_tm Ctx A DA1
DB1 : desugar_tm Ctx B DB1
H1 : is_tm A
H2 : is_tm B
============================
app DA1 DB1 = app DA1 DB1
< search.
Subgoal 3.2:
Variables: Ctx TB DB DA B A T_P
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (app A B)
DA : desugar_tm Ctx A DA *
DA1 : desugar_tm Ctx B DB *
DB : Ctx |{tm}- app A B ~~> T_P
DB1 : desugar_tm Ctx T_P TB
============================
app DA DB = TB
< case DB.
Subgoal 4:
Variables: Ctx TB I
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (num I)
DB : desugar_tm Ctx (num I) TB
============================
num I = TB
< DB: case DB.
Subgoal 4.1:
Variables: Ctx I
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (num I)
============================
num I = num I
< search.
Subgoal 4.2:
Variables: Ctx TB I T_P
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (num I)
DB : Ctx |{tm}- num I ~~> T_P
DB1 : desugar_tm Ctx T_P TB
============================
num I = TB
< case DB.
Subgoal 5:
Variables: Ctx TB DB DA B A
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (plus A B)
DB : desugar_tm Ctx (plus A B) TB
DA : desugar_tm Ctx A DA *
DA1 : desugar_tm Ctx B DB *
============================
plus DA DB = TB
< DB: case DB.
Subgoal 5.1:
Variables: Ctx DB DA B A DB1 DA1
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (plus A B)
DA : desugar_tm Ctx A DA *
DA1 : desugar_tm Ctx B DB *
DB : desugar_tm Ctx A DA1
DB1 : desugar_tm Ctx B DB1
============================
plus DA DB = plus DA1 DB1
< case IsT.
Subgoal 5.1:
Variables: Ctx DB DA B A DB1 DA1
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
DA : desugar_tm Ctx A DA *
DA1 : desugar_tm Ctx B DB *
DB : desugar_tm Ctx A DA1
DB1 : desugar_tm Ctx B DB1
H1 : is_tm A
H2 : is_tm B
============================
plus DA DB = plus DA1 DB1
< apply IH to _ _ DA DB.
Subgoal 5.1:
Variables: Ctx DB B A DB1 DA1
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
DA : desugar_tm Ctx A DA1 *
DA1 : desugar_tm Ctx B DB *
DB : desugar_tm Ctx A DA1
DB1 : desugar_tm Ctx B DB1
H1 : is_tm A
H2 : is_tm B
============================
plus DA1 DB = plus DA1 DB1
< apply IH to _ _ DA1 DB1.
Subgoal 5.1:
Variables: Ctx B A DB1 DA1
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
DA : desugar_tm Ctx A DA1 *
DA1 : desugar_tm Ctx B DB1 *
DB : desugar_tm Ctx A DA1
DB1 : desugar_tm Ctx B DB1
H1 : is_tm A
H2 : is_tm B
============================
plus DA1 DB1 = plus DA1 DB1
< search.
Subgoal 5.2:
Variables: Ctx TB DB DA B A T_P
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (plus A B)
DA : desugar_tm Ctx A DA *
DA1 : desugar_tm Ctx B DB *
DB : Ctx |{tm}- plus A B ~~> T_P
DB1 : desugar_tm Ctx T_P TB
============================
plus DA DB = TB
< case DB.
Subgoal 6:
Variables: Ctx T TA TB T_P
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm T
DB : desugar_tm Ctx T TB
DA : Ctx |{tm}- T ~~> T_P
DA1 : desugar_tm Ctx T_P TA *
============================
TA = TB
< DB: case DB.
Subgoal 6.1:
Variables: Ctx TA T_P X
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (var X)
DA : Ctx |{tm}- var X ~~> T_P
DA1 : desugar_tm Ctx T_P TA *
============================
TA = var X
< case DA.
Subgoal 6.2:
Variables: Ctx TA T_P DTm DTy X Tm Ty
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (abs X Ty Tm)
DA : Ctx |{tm}- abs X Ty Tm ~~> T_P
DA1 : desugar_tm Ctx T_P TA *
DB : desugar_ty Ty DTy
DB1 : desugar_tm ((X, Ty)::Ctx) Tm DTm
============================
TA = abs X DTy DTm
< case DA.
Subgoal 6.3:
Variables: Ctx TA T_P DB DA B A
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (app A B)
DA : Ctx |{tm}- app A B ~~> T_P
DA1 : desugar_tm Ctx T_P TA *
DB : desugar_tm Ctx A DA
DB1 : desugar_tm Ctx B DB
============================
TA = app DA DB
< case DA.
Subgoal 6.4:
Variables: Ctx TA T_P I
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (num I)
DA : Ctx |{tm}- num I ~~> T_P
DA1 : desugar_tm Ctx T_P TA *
============================
TA = num I
< case DA.
Subgoal 6.5:
Variables: Ctx TA T_P DB DA B A
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm (plus A B)
DA : Ctx |{tm}- plus A B ~~> T_P
DA1 : desugar_tm Ctx T_P TA *
DB : desugar_tm Ctx A DA
DB1 : desugar_tm Ctx B DB
============================
TA = plus DA DB
< case DA.
Subgoal 6.6:
Variables: Ctx T TA TB T_P T_P1
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm T
DA : Ctx |{tm}- T ~~> T_P
DA1 : desugar_tm Ctx T_P TA *
DB : Ctx |{tm}- T ~~> T_P1
DB1 : desugar_tm Ctx T_P1 TB
============================
TA = TB
< apply proj_tm_unique to DA DB _ _.
Subgoal 6.6:
Variables: Ctx T TA TB T_P1
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm T
DA : Ctx |{tm}- T ~~> T_P1
DA1 : desugar_tm Ctx T_P1 TA *
DB : Ctx |{tm}- T ~~> T_P1
DB1 : desugar_tm Ctx T_P1 TB
============================
TA = TB
< apply proj_is to DA _ _.
Subgoal 6.6:
Variables: Ctx T TA TB T_P1
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm T
DA : Ctx |{tm}- T ~~> T_P1
DA1 : desugar_tm Ctx T_P1 TA *
DB : Ctx |{tm}- T ~~> T_P1
DB1 : desugar_tm Ctx T_P1 TB
H1 : is_tm T_P1
============================
TA = TB
< apply IH to _ _ DA1 DB1.
Subgoal 6.6:
Variables: Ctx T TB T_P1
IH : forall Ctx T TA TB,
is_list (is_pair is_string is_ty) Ctx -> is_tm T -> desugar_tm Ctx T TA * ->
desugar_tm Ctx T TB -> TA = TB
IsCtx : is_list (is_pair is_string is_ty) Ctx
IsT : is_tm T
DA : Ctx |{tm}- T ~~> T_P1
DA1 : desugar_tm Ctx T_P1 TB *
DB : Ctx |{tm}- T ~~> T_P1
DB1 : desugar_tm Ctx T_P1 TB
H1 : is_tm T_P1
============================
TB = TB
< search.
Proof completed.
< Extensible_Theorem
desugar_ty_exists : forall Ty,
IsTy : is_ty Ty ->
exists Ty',
desugar_ty Ty Ty'
on IsTy.
Subgoal 1:
Variables: Ty2 Ty1
IH : forall Ty, is_ty Ty * -> exists Ty', desugar_ty Ty Ty'
IsTy : is_ty (arrowTy Ty1 Ty2) @
IsTy1 : is_ty Ty1 *
IsTy2 : is_ty Ty2 *
============================
exists Ty', desugar_ty (arrowTy Ty1 Ty2) Ty'
< apply IH to IsTy1.
Subgoal 1:
Variables: Ty2 Ty1 Ty'
IH : forall Ty, is_ty Ty * -> exists Ty', desugar_ty Ty Ty'
IsTy : is_ty (arrowTy Ty1 Ty2) @
IsTy1 : is_ty Ty1 *
IsTy2 : is_ty Ty2 *
H1 : desugar_ty Ty1 Ty'
============================
exists Ty', desugar_ty (arrowTy Ty1 Ty2) Ty'
< apply IH to IsTy2.
Subgoal 1:
Variables: Ty2 Ty1 Ty' Ty'1
IH : forall Ty, is_ty Ty * -> exists Ty', desugar_ty Ty Ty'
IsTy : is_ty (arrowTy Ty1 Ty2) @
IsTy1 : is_ty Ty1 *
IsTy2 : is_ty Ty2 *
H1 : desugar_ty Ty1 Ty'
H2 : desugar_ty Ty2 Ty'1
============================
exists Ty', desugar_ty (arrowTy Ty1 Ty2) Ty'
< search.
Subgoal 2:
IH : forall Ty, is_ty Ty * -> exists Ty', desugar_ty Ty Ty'
IsTy : is_ty intTy @
============================
exists Ty', desugar_ty intTy Ty'
< search.
Proof completed.
< Define host_is_ty : ty -> prop by
host_is_ty (arrowTy Ty1 Ty2) :=
host_is_ty Ty1 /\ host_is_ty Ty2;
host_is_ty intTy.
< Define host_is_tm : tm -> prop by
host_is_tm (var X) :=
is_string X;
host_is_tm (abs X Ty B) :=
(is_string X /\ host_is_ty Ty) /\ host_is_tm B;
host_is_tm (app A B) :=
host_is_tm A /\ host_is_tm B;
host_is_tm (num I) :=
is_integer I;
host_is_tm (plus A B) :=
host_is_tm A /\ host_is_tm B.
< Theorem desugar_ty_host_is_ty :
forall Ty DTy, is_ty Ty -> desugar_ty Ty DTy -> host_is_ty DTy.
============================
forall Ty DTy, is_ty Ty -> desugar_ty Ty DTy -> host_is_ty DTy
< induction on 2.
IH : forall Ty DTy, is_ty Ty -> desugar_ty Ty DTy * -> host_is_ty DTy
============================
forall Ty DTy, is_ty Ty -> desugar_ty Ty DTy @ -> host_is_ty DTy
< intros IsTy DS.
Variables: Ty DTy
IH : forall Ty DTy, is_ty Ty -> desugar_ty Ty DTy * -> host_is_ty DTy
IsTy : is_ty Ty
DS : desugar_ty Ty DTy @
============================
host_is_ty DTy
< DS: case DS.
Subgoal 1:
Variables: DB DA B A
IH : forall Ty DTy, is_ty Ty -> desugar_ty Ty DTy * -> host_is_ty DTy
IsTy : is_ty (arrowTy A B)
DS : desugar_ty A DA *
DS1 : desugar_ty B DB *
============================
host_is_ty (arrowTy DA DB)
< case IsTy.
Subgoal 1:
Variables: DB DA B A
IH : forall Ty DTy, is_ty Ty -> desugar_ty Ty DTy * -> host_is_ty DTy
DS : desugar_ty A DA *
DS1 : desugar_ty B DB *
H1 : is_ty A
H2 : is_ty B
============================
host_is_ty (arrowTy DA DB)
< apply IH to _ DS.
Subgoal 1:
Variables: DB DA B A
IH : forall Ty DTy, is_ty Ty -> desugar_ty Ty DTy * -> host_is_ty DTy
DS : desugar_ty A DA *
DS1 : desugar_ty B DB *
H1 : is_ty A
H2 : is_ty B
H3 : host_is_ty DA
============================
host_is_ty (arrowTy DA DB)
< apply IH to _ DS1.
Subgoal 1:
Variables: DB DA B A
IH : forall Ty DTy, is_ty Ty -> desugar_ty Ty DTy * -> host_is_ty DTy
DS : desugar_ty A DA *
DS1 : desugar_ty B DB *
H1 : is_ty A
H2 : is_ty B
H3 : host_is_ty DA
H4 : host_is_ty DB
============================
host_is_ty (arrowTy DA DB)
< search.
Subgoal 2:
IH : forall Ty DTy, is_ty Ty -> desugar_ty Ty DTy * -> host_is_ty DTy
IsTy : is_ty intTy
============================
host_is_ty intTy
< search.
Subgoal 3:
Variables: Ty DTy Ty_P
IH : forall Ty DTy, is_ty Ty -> desugar_ty Ty DTy * -> host_is_ty DTy
IsTy : is_ty Ty
DS : |{ty}- Ty ~~> Ty_P
DS1 : desugar_ty Ty_P DTy *
============================
host_is_ty DTy
< apply proj_ty_is to DS _.
Subgoal 3:
Variables: Ty DTy Ty_P
IH : forall Ty DTy, is_ty Ty -> desugar_ty Ty DTy * -> host_is_ty DTy
IsTy : is_ty Ty
DS : |{ty}- Ty ~~> Ty_P
DS1 : desugar_ty Ty_P DTy *
H1 : is_ty Ty_P
============================
host_is_ty DTy
< apply IH to _ DS1.
Subgoal 3:
Variables: Ty DTy Ty_P
IH : forall Ty DTy, is_ty Ty -> desugar_ty Ty DTy * -> host_is_ty DTy
IsTy : is_ty Ty
DS : |{ty}- Ty ~~> Ty_P
DS1 : desugar_ty Ty_P DTy *
H1 : is_ty Ty_P
H2 : host_is_ty DTy
============================
host_is_ty DTy
< search.
Proof completed.
< Theorem desugar_tm_host_is_tm :
forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT ->
host_is_tm DT.
============================
forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT -> host_is_tm DT
< induction on 3.
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
============================
forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT @ -> host_is_tm DT
< intros IsT IsCtx DS.
Variables: Ctx T DT
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsT : is_tm T
IsCtx : is_list (is_pair is_string is_ty) Ctx
DS : desugar_tm Ctx T DT @
============================
host_is_tm DT
< DS: case DS.
Subgoal 1:
Variables: Ctx X
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsT : is_tm (var X)
IsCtx : is_list (is_pair is_string is_ty) Ctx
============================
host_is_tm (var X)
< case IsT.
Subgoal 1:
Variables: Ctx X
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsCtx : is_list (is_pair is_string is_ty) Ctx
H1 : is_string X
============================
host_is_tm (var X)
< search.
Subgoal 2:
Variables: Ctx DTm DTy X Tm Ty
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsT : is_tm (abs X Ty Tm)
IsCtx : is_list (is_pair is_string is_ty) Ctx
DS : desugar_ty Ty DTy
DS1 : desugar_tm ((X, Ty)::Ctx) Tm DTm *
============================
host_is_tm (abs X DTy DTm)
< case IsT.
Subgoal 2:
Variables: Ctx DTm DTy X Tm Ty
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsCtx : is_list (is_pair is_string is_ty) Ctx
DS : desugar_ty Ty DTy
DS1 : desugar_tm ((X, Ty)::Ctx) Tm DTm *
H1 : is_string X
H2 : is_ty Ty
H3 : is_tm Tm
============================
host_is_tm (abs X DTy DTm)
< apply desugar_ty_host_is_ty to _ DS.
Subgoal 2:
Variables: Ctx DTm DTy X Tm Ty
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsCtx : is_list (is_pair is_string is_ty) Ctx
DS : desugar_ty Ty DTy
DS1 : desugar_tm ((X, Ty)::Ctx) Tm DTm *
H1 : is_string X
H2 : is_ty Ty
H3 : is_tm Tm
H4 : host_is_ty DTy
============================
host_is_tm (abs X DTy DTm)
< apply IH to _ _ DS1.
Subgoal 2:
Variables: Ctx DTm DTy X Tm Ty
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsCtx : is_list (is_pair is_string is_ty) Ctx
DS : desugar_ty Ty DTy
DS1 : desugar_tm ((X, Ty)::Ctx) Tm DTm *
H1 : is_string X
H2 : is_ty Ty
H3 : is_tm Tm
H4 : host_is_ty DTy
H5 : host_is_tm DTm
============================
host_is_tm (abs X DTy DTm)
< search.
Subgoal 3:
Variables: Ctx DB DA B A
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsT : is_tm (app A B)
IsCtx : is_list (is_pair is_string is_ty) Ctx
DS : desugar_tm Ctx A DA *
DS1 : desugar_tm Ctx B DB *
============================
host_is_tm (app DA DB)
< case IsT.
Subgoal 3:
Variables: Ctx DB DA B A
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsCtx : is_list (is_pair is_string is_ty) Ctx
DS : desugar_tm Ctx A DA *
DS1 : desugar_tm Ctx B DB *
H1 : is_tm A
H2 : is_tm B
============================
host_is_tm (app DA DB)
< apply IH to _ _ DS.
Subgoal 3:
Variables: Ctx DB DA B A
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsCtx : is_list (is_pair is_string is_ty) Ctx
DS : desugar_tm Ctx A DA *
DS1 : desugar_tm Ctx B DB *
H1 : is_tm A
H2 : is_tm B
H3 : host_is_tm DA
============================
host_is_tm (app DA DB)
< apply IH to _ _ DS1.
Subgoal 3:
Variables: Ctx DB DA B A
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsCtx : is_list (is_pair is_string is_ty) Ctx
DS : desugar_tm Ctx A DA *
DS1 : desugar_tm Ctx B DB *
H1 : is_tm A
H2 : is_tm B
H3 : host_is_tm DA
H4 : host_is_tm DB
============================
host_is_tm (app DA DB)
< search.
Subgoal 4:
Variables: Ctx I
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsT : is_tm (num I)
IsCtx : is_list (is_pair is_string is_ty) Ctx
============================
host_is_tm (num I)
< case IsT.
Subgoal 4:
Variables: Ctx I
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsCtx : is_list (is_pair is_string is_ty) Ctx
H1 : is_integer I
============================
host_is_tm (num I)
< search.
Subgoal 5:
Variables: Ctx DB DA B A
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsT : is_tm (plus A B)
IsCtx : is_list (is_pair is_string is_ty) Ctx
DS : desugar_tm Ctx A DA *
DS1 : desugar_tm Ctx B DB *
============================
host_is_tm (plus DA DB)
< case IsT.
Subgoal 5:
Variables: Ctx DB DA B A
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsCtx : is_list (is_pair is_string is_ty) Ctx
DS : desugar_tm Ctx A DA *
DS1 : desugar_tm Ctx B DB *
H1 : is_tm A
H2 : is_tm B
============================
host_is_tm (plus DA DB)
< apply IH to _ _ DS.
Subgoal 5:
Variables: Ctx DB DA B A
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsCtx : is_list (is_pair is_string is_ty) Ctx
DS : desugar_tm Ctx A DA *
DS1 : desugar_tm Ctx B DB *
H1 : is_tm A
H2 : is_tm B
H3 : host_is_tm DA
============================
host_is_tm (plus DA DB)
< apply IH to _ _ DS1.
Subgoal 5:
Variables: Ctx DB DA B A
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsCtx : is_list (is_pair is_string is_ty) Ctx
DS : desugar_tm Ctx A DA *
DS1 : desugar_tm Ctx B DB *
H1 : is_tm A
H2 : is_tm B
H3 : host_is_tm DA
H4 : host_is_tm DB
============================
host_is_tm (plus DA DB)
< search.
Subgoal 6:
Variables: Ctx T DT T_P
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsT : is_tm T
IsCtx : is_list (is_pair is_string is_ty) Ctx
DS : Ctx |{tm}- T ~~> T_P
DS1 : desugar_tm Ctx T_P DT *
============================
host_is_tm DT
< apply proj_is to DS _ _.
Subgoal 6:
Variables: Ctx T DT T_P
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsT : is_tm T
IsCtx : is_list (is_pair is_string is_ty) Ctx
DS : Ctx |{tm}- T ~~> T_P
DS1 : desugar_tm Ctx T_P DT *
H1 : is_tm T_P
============================
host_is_tm DT
< apply IH to _ _ DS1.
Subgoal 6:
Variables: Ctx T DT T_P
IH : forall Ctx T DT,
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> desugar_tm Ctx T DT * ->
host_is_tm DT
IsT : is_tm T
IsCtx : is_list (is_pair is_string is_ty) Ctx
DS : Ctx |{tm}- T ~~> T_P
DS1 : desugar_tm Ctx T_P DT *
H1 : is_tm T_P
H2 : host_is_tm DT
============================
host_is_tm DT
< search.
Proof completed.
< Extensible_Theorem
desugar_ty_rel : forall Ctx T Ty T' Ty' Ctx',
IsT : is_tm T ->
IsCtx : is_list (is_pair is_string is_ty) Ctx ->
Ty : typeOf Ctx T Ty ->
DT : desugar_tm Ctx T T' ->
DTy : desugar_ty Ty Ty' ->
DCtx : desugar_ctx Ctx Ctx' ->
typeOf Ctx' T' Ty'
on Ty.
Subgoal 1:
Variables: Ctx Ty T' Ty' Ctx' X
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsT : is_tm (var X)
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (var X) Ty @
DT : desugar_tm Ctx (var X) T'
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : lookup Ctx X Ty
============================
typeOf Ctx' T' Ty'
< L: apply lookup_desugar_ctx to Ty1 DCtx.
Subgoal 1:
Variables: Ctx Ty T' Ty' Ctx' X Ty'1
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsT : is_tm (var X)
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (var X) Ty @
DT : desugar_tm Ctx (var X) T'
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : lookup Ctx X Ty
L : lookup Ctx' X Ty'1
L1 : desugar_ty Ty Ty'1
============================
typeOf Ctx' T' Ty'
< DT: case DT.
Subgoal 1.1:
Variables: Ctx Ty Ty' Ctx' X Ty'1
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsT : is_tm (var X)
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (var X) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : lookup Ctx X Ty
L : lookup Ctx' X Ty'1
L1 : desugar_ty Ty Ty'1
============================
typeOf Ctx' (var X) Ty'
< apply lookup_ty_is to _ Ty1.
Subgoal 1.1:
Variables: Ctx Ty Ty' Ctx' X Ty'1
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsT : is_tm (var X)
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (var X) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : lookup Ctx X Ty
L : lookup Ctx' X Ty'1
L1 : desugar_ty Ty Ty'1
H1 : is_ty Ty
============================
typeOf Ctx' (var X) Ty'
< apply desugar_ty_unique to _ L1 DTy.
Subgoal 1.1:
Variables: Ctx Ty Ty' Ctx' X
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsT : is_tm (var X)
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (var X) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : lookup Ctx X Ty
L : lookup Ctx' X Ty'
L1 : desugar_ty Ty Ty'
H1 : is_ty Ty
============================
typeOf Ctx' (var X) Ty'
< search.
Subgoal 1.2:
Variables: Ctx Ty T' Ty' Ctx' X Ty'1 T_P
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsT : is_tm (var X)
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (var X) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : lookup Ctx X Ty
L : lookup Ctx' X Ty'1
L1 : desugar_ty Ty Ty'1
DT : Ctx |{tm}- var X ~~> T_P
DT1 : desugar_tm Ctx T_P T'
============================
typeOf Ctx' T' Ty'
< case DT.
Subgoal 2:
Variables: Ctx T' Ty' Ctx' Ty2 Ty1 Body X
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsT : is_tm (abs X Ty1 Body)
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
DT : desugar_tm Ctx (abs X Ty1 Body) T'
DTy : desugar_ty (arrowTy Ty1 Ty2) Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf ((X, Ty1)::Ctx) Body Ty2 *
============================
typeOf Ctx' T' Ty'
< case IsT.
Subgoal 2:
Variables: Ctx T' Ty' Ctx' Ty2 Ty1 Body X
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
DT : desugar_tm Ctx (abs X Ty1 Body) T'
DTy : desugar_ty (arrowTy Ty1 Ty2) Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf ((X, Ty1)::Ctx) Body Ty2 *
H1 : is_string X
H2 : is_ty Ty1
H3 : is_tm Body
============================
typeOf Ctx' T' Ty'
< DT: case DT.
Subgoal 2.1:
Variables: Ctx Ty' Ctx' Ty2 Ty1 Body X DTm DTy
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
DTy : desugar_ty (arrowTy Ty1 Ty2) Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf ((X, Ty1)::Ctx) Body Ty2 *
H1 : is_string X
H2 : is_ty Ty1
H3 : is_tm Body
DT : desugar_ty Ty1 DTy
DT1 : desugar_tm ((X, Ty1)::Ctx) Body DTm
============================
typeOf Ctx' (abs X DTy DTm) Ty'
< DTy: case DTy.
Subgoal 2.1.1:
Variables: Ctx Ctx' Ty2 Ty1 Body X DTm DTy DB DA
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf ((X, Ty1)::Ctx) Body Ty2 *
H1 : is_string X
H2 : is_ty Ty1
H3 : is_tm Body
DT : desugar_ty Ty1 DTy
DT1 : desugar_tm ((X, Ty1)::Ctx) Body DTm
DTy : desugar_ty Ty1 DA
DTy1 : desugar_ty Ty2 DB
============================
typeOf Ctx' (abs X DTy DTm) (arrowTy DA DB)
< apply desugar_ty_unique to _ DT DTy.
Subgoal 2.1.1:
Variables: Ctx Ctx' Ty2 Ty1 Body X DTm DB DA
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf ((X, Ty1)::Ctx) Body Ty2 *
H1 : is_string X
H2 : is_ty Ty1
H3 : is_tm Body
DT : desugar_ty Ty1 DA
DT1 : desugar_tm ((X, Ty1)::Ctx) Body DTm
DTy : desugar_ty Ty1 DA
DTy1 : desugar_ty Ty2 DB
============================
typeOf Ctx' (abs X DA DTm) (arrowTy DA DB)
< apply IH to _ _ Ty1 DT1 DTy1 _.
Subgoal 2.1.1:
Variables: Ctx Ctx' Ty2 Ty1 Body X DTm DB DA
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf ((X, Ty1)::Ctx) Body Ty2 *
H1 : is_string X
H2 : is_ty Ty1
H3 : is_tm Body
DT : desugar_ty Ty1 DA
DT1 : desugar_tm ((X, Ty1)::Ctx) Body DTm
DTy : desugar_ty Ty1 DA
DTy1 : desugar_ty Ty2 DB
H4 : typeOf ((X, DA)::Ctx') DTm DB
============================
typeOf Ctx' (abs X DA DTm) (arrowTy DA DB)
< search.
Subgoal 2.1.2:
Variables: Ctx Ty' Ctx' Ty2 Ty1 Body X DTm DTy Ty_P
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf ((X, Ty1)::Ctx) Body Ty2 *
H1 : is_string X
H2 : is_ty Ty1
H3 : is_tm Body
DT : desugar_ty Ty1 DTy
DT1 : desugar_tm ((X, Ty1)::Ctx) Body DTm
DTy : |{ty}- arrowTy Ty1 Ty2 ~~> Ty_P
DTy1 : desugar_ty Ty_P Ty'
============================
typeOf Ctx' (abs X DTy DTm) Ty'
< case DTy.
Subgoal 2.2:
Variables: Ctx T' Ty' Ctx' Ty2 Ty1 Body X T_P
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (abs X Ty1 Body) (arrowTy Ty1 Ty2) @
DTy : desugar_ty (arrowTy Ty1 Ty2) Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf ((X, Ty1)::Ctx) Body Ty2 *
H1 : is_string X
H2 : is_ty Ty1
H3 : is_tm Body
DT : Ctx |{tm}- abs X Ty1 Body ~~> T_P
DT1 : desugar_tm Ctx T_P T'
============================
typeOf Ctx' T' Ty'
< case DT.
Subgoal 3:
Variables: Ctx Ty T' Ty' Ctx' Ty1 T2 T1
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsT : is_tm (app T1 T2)
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (app T1 T2) Ty @
DT : desugar_tm Ctx (app T1 T2) T'
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx T2 Ty1 *
============================
typeOf Ctx' T' Ty'
< case IsT.
Subgoal 3:
Variables: Ctx Ty T' Ty' Ctx' Ty1 T2 T1
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (app T1 T2) Ty @
DT : desugar_tm Ctx (app T1 T2) T'
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx T2 Ty1 *
H1 : is_tm T1
H2 : is_tm T2
============================
typeOf Ctx' T' Ty'
< DT: case DT.
Subgoal 3.1:
Variables: Ctx Ty Ty' Ctx' Ty1 T2 T1 DB DA
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (app T1 T2) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx T2 Ty1 *
H1 : is_tm T1
H2 : is_tm T2
DT : desugar_tm Ctx T1 DA
DT1 : desugar_tm Ctx T2 DB
============================
typeOf Ctx' (app DA DB) Ty'
< IsTy: apply type_is to _ _ Ty1.
Subgoal 3.1:
Variables: Ctx Ty Ty' Ctx' Ty1 T2 T1 DB DA
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (app T1 T2) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx T2 Ty1 *
H1 : is_tm T1
H2 : is_tm T2
DT : desugar_tm Ctx T1 DA
DT1 : desugar_tm Ctx T2 DB
IsTy : is_ty (arrowTy Ty1 Ty)
============================
typeOf Ctx' (app DA DB) Ty'
< Is: case IsTy.
Subgoal 3.1:
Variables: Ctx Ty Ty' Ctx' Ty1 T2 T1 DB DA
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (app T1 T2) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx T2 Ty1 *
H1 : is_tm T1
H2 : is_tm T2
DT : desugar_tm Ctx T1 DA
DT1 : desugar_tm Ctx T2 DB
Is : is_ty Ty1
Is1 : is_ty Ty
============================
typeOf Ctx' (app DA DB) Ty'
< apply desugar_ty_exists to Is.
Subgoal 3.1:
Variables: Ctx Ty Ty' Ctx' Ty1 T2 T1 DB DA Ty'1
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (app T1 T2) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx T2 Ty1 *
H1 : is_tm T1
H2 : is_tm T2
DT : desugar_tm Ctx T1 DA
DT1 : desugar_tm Ctx T2 DB
Is : is_ty Ty1
Is1 : is_ty Ty
H3 : desugar_ty Ty1 Ty'1
============================
typeOf Ctx' (app DA DB) Ty'
< apply desugar_ty_exists to Is1.
Subgoal 3.1:
Variables: Ctx Ty Ty' Ctx' Ty1 T2 T1 DB DA Ty'1 Ty'2
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (app T1 T2) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx T2 Ty1 *
H1 : is_tm T1
H2 : is_tm T2
DT : desugar_tm Ctx T1 DA
DT1 : desugar_tm Ctx T2 DB
Is : is_ty Ty1
Is1 : is_ty Ty
H3 : desugar_ty Ty1 Ty'1
H4 : desugar_ty Ty Ty'2
============================
typeOf Ctx' (app DA DB) Ty'
< apply IH to _ _ Ty1 DT _ _.
Subgoal 3.1:
Variables: Ctx Ty Ty' Ctx' Ty1 T2 T1 DB DA Ty'1 Ty'2
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (app T1 T2) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx T2 Ty1 *
H1 : is_tm T1
H2 : is_tm T2
DT : desugar_tm Ctx T1 DA
DT1 : desugar_tm Ctx T2 DB
Is : is_ty Ty1
Is1 : is_ty Ty
H3 : desugar_ty Ty1 Ty'1
H4 : desugar_ty Ty Ty'2
H5 : typeOf Ctx' DA (arrowTy Ty'1 Ty')
============================
typeOf Ctx' (app DA DB) Ty'
< apply IH to _ _ Ty2 DT1 _ _.
Subgoal 3.1:
Variables: Ctx Ty Ty' Ctx' Ty1 T2 T1 DB DA Ty'1 Ty'2
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (app T1 T2) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx T2 Ty1 *
H1 : is_tm T1
H2 : is_tm T2
DT : desugar_tm Ctx T1 DA
DT1 : desugar_tm Ctx T2 DB
Is : is_ty Ty1
Is1 : is_ty Ty
H3 : desugar_ty Ty1 Ty'1
H4 : desugar_ty Ty Ty'2
H5 : typeOf Ctx' DA (arrowTy Ty'1 Ty')
H6 : typeOf Ctx' DB Ty'1
============================
typeOf Ctx' (app DA DB) Ty'
< search.
Subgoal 3.2:
Variables: Ctx Ty T' Ty' Ctx' Ty1 T2 T1 T_P
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (app T1 T2) Ty @
DTy : desugar_ty Ty Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 (arrowTy Ty1 Ty) *
Ty2 : typeOf Ctx T2 Ty1 *
H1 : is_tm T1
H2 : is_tm T2
DT : Ctx |{tm}- app T1 T2 ~~> T_P
DT1 : desugar_tm Ctx T_P T'
============================
typeOf Ctx' T' Ty'
< case DT.
Subgoal 4:
Variables: Ctx T' Ty' Ctx' I
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsT : is_tm (num I)
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (num I) intTy @
DT : desugar_tm Ctx (num I) T'
DTy : desugar_ty intTy Ty'
DCtx : desugar_ctx Ctx Ctx'
============================
typeOf Ctx' T' Ty'
< DT: case DT.
Subgoal 4.1:
Variables: Ctx Ty' Ctx' I
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsT : is_tm (num I)
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (num I) intTy @
DTy : desugar_ty intTy Ty'
DCtx : desugar_ctx Ctx Ctx'
============================
typeOf Ctx' (num I) Ty'
< DTy: case DTy.
Subgoal 4.1.1:
Variables: Ctx Ctx' I
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsT : is_tm (num I)
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (num I) intTy @
DCtx : desugar_ctx Ctx Ctx'
============================
typeOf Ctx' (num I) intTy
< search.
Subgoal 4.1.2:
Variables: Ctx Ty' Ctx' I Ty_P
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsT : is_tm (num I)
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (num I) intTy @
DCtx : desugar_ctx Ctx Ctx'
DTy : |{ty}- intTy ~~> Ty_P
DTy1 : desugar_ty Ty_P Ty'
============================
typeOf Ctx' (num I) Ty'
< case DTy.
Subgoal 4.2:
Variables: Ctx T' Ty' Ctx' I T_P
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsT : is_tm (num I)
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (num I) intTy @
DTy : desugar_ty intTy Ty'
DCtx : desugar_ctx Ctx Ctx'
DT : Ctx |{tm}- num I ~~> T_P
DT1 : desugar_tm Ctx T_P T'
============================
typeOf Ctx' T' Ty'
< case DT.
Subgoal 5:
Variables: Ctx T' Ty' Ctx' T2 T1
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsT : is_tm (plus T1 T2)
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (plus T1 T2) intTy @
DT : desugar_tm Ctx (plus T1 T2) T'
DTy : desugar_ty intTy Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 intTy *
Ty2 : typeOf Ctx T2 intTy *
============================
typeOf Ctx' T' Ty'
< case IsT.
Subgoal 5:
Variables: Ctx T' Ty' Ctx' T2 T1
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (plus T1 T2) intTy @
DT : desugar_tm Ctx (plus T1 T2) T'
DTy : desugar_ty intTy Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 intTy *
Ty2 : typeOf Ctx T2 intTy *
H1 : is_tm T1
H2 : is_tm T2
============================
typeOf Ctx' T' Ty'
< DT: case DT.
Subgoal 5.1:
Variables: Ctx Ty' Ctx' T2 T1 DB DA
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (plus T1 T2) intTy @
DTy : desugar_ty intTy Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 intTy *
Ty2 : typeOf Ctx T2 intTy *
H1 : is_tm T1
H2 : is_tm T2
DT : desugar_tm Ctx T1 DA
DT1 : desugar_tm Ctx T2 DB
============================
typeOf Ctx' (plus DA DB) Ty'
< DTy: case DTy.
Subgoal 5.1.1:
Variables: Ctx Ctx' T2 T1 DB DA
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (plus T1 T2) intTy @
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 intTy *
Ty2 : typeOf Ctx T2 intTy *
H1 : is_tm T1
H2 : is_tm T2
DT : desugar_tm Ctx T1 DA
DT1 : desugar_tm Ctx T2 DB
============================
typeOf Ctx' (plus DA DB) intTy
< apply IH to _ _ Ty1 DT _ _.
Subgoal 5.1.1:
Variables: Ctx Ctx' T2 T1 DB DA
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (plus T1 T2) intTy @
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 intTy *
Ty2 : typeOf Ctx T2 intTy *
H1 : is_tm T1
H2 : is_tm T2
DT : desugar_tm Ctx T1 DA
DT1 : desugar_tm Ctx T2 DB
H3 : typeOf Ctx' DA intTy
============================
typeOf Ctx' (plus DA DB) intTy
< apply IH to _ _ Ty2 DT1 _ _.
Subgoal 5.1.1:
Variables: Ctx Ctx' T2 T1 DB DA
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (plus T1 T2) intTy @
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 intTy *
Ty2 : typeOf Ctx T2 intTy *
H1 : is_tm T1
H2 : is_tm T2
DT : desugar_tm Ctx T1 DA
DT1 : desugar_tm Ctx T2 DB
H3 : typeOf Ctx' DA intTy
H4 : typeOf Ctx' DB intTy
============================
typeOf Ctx' (plus DA DB) intTy
< search.
Subgoal 5.1.2:
Variables: Ctx Ty' Ctx' T2 T1 DB DA Ty_P
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (plus T1 T2) intTy @
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 intTy *
Ty2 : typeOf Ctx T2 intTy *
H1 : is_tm T1
H2 : is_tm T2
DT : desugar_tm Ctx T1 DA
DT1 : desugar_tm Ctx T2 DB
DTy : |{ty}- intTy ~~> Ty_P
DTy1 : desugar_ty Ty_P Ty'
============================
typeOf Ctx' (plus DA DB) Ty'
< case DTy.
Subgoal 5.2:
Variables: Ctx T' Ty' Ctx' T2 T1 T_P
IH : forall Ctx T Ty T' Ty' Ctx',
is_tm T -> is_list (is_pair is_string is_ty) Ctx -> typeOf Ctx T Ty * -> desugar_tm Ctx T T' ->
desugar_ty Ty Ty' -> desugar_ctx Ctx Ctx' -> typeOf Ctx' T' Ty'
IsCtx : is_list (is_pair is_string is_ty) Ctx
Ty : typeOf Ctx (plus T1 T2) intTy @
DTy : desugar_ty intTy Ty'
DCtx : desugar_ctx Ctx Ctx'
Ty1 : typeOf Ctx T1 intTy *
Ty2 : typeOf Ctx T2 intTy *
H1 : is_tm T1
H2 : is_tm T2
DT : Ctx |{tm}- plus T1 T2 ~~> T_P
DT1 : desugar_tm Ctx T_P T'
============================
typeOf Ctx' T' Ty'
< case DT.
Proof completed.
< Theorem subst_is :
forall X R T S,
is_tm T -> is_string X -> is_tm R -> subst X R T S -> is_tm S.
============================
forall X R T S, is_tm T -> is_string X -> is_tm R -> subst X R T S -> is_tm S
< induction on 4.
IH : forall X R T S,
is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S
============================
forall X R T S, is_tm T -> is_string X -> is_tm R -> subst X R T S @ -> is_tm S
< intros IsT IsX IsR S.
Variables: X R T S
IH : forall X R T S,
is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S
IsT : is_tm T
IsX : is_string X
IsR : is_tm R
S : subst X R T S @
============================
is_tm S
< S: case S.
Subgoal 1:
Variables: X R Y
IH : forall X R T S,
is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S
IsT : is_tm (var Y)
IsX : is_string X
IsR : is_tm R
S : X = Y -> false
============================
is_tm (var Y)
< search.
Subgoal 2:
Variables: X S
IH : forall X R T S,
is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S
IsT : is_tm (var X)
IsX : is_string X
IsR : is_tm S
============================
is_tm S
< search.
Subgoal 3:
Variables: X R S1 Ty Y B
IH : forall X R T S,
is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S
IsT : is_tm (abs Y Ty B)
IsX : is_string X
IsR : is_tm R
S : X = Y -> false
S1 : subst X R B S1 *
============================
is_tm (abs Y Ty S1)
< Is: case IsT.
Subgoal 3:
Variables: X R S1 Ty Y B
IH : forall X R T S,
is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S
IsX : is_string X
IsR : is_tm R
S : X = Y -> false
S1 : subst X R B S1 *
Is : is_string Y
Is1 : is_ty Ty
Is2 : is_tm B
============================
is_tm (abs Y Ty S1)
< apply IH to _ _ _ S1.
Subgoal 3:
Variables: X R S1 Ty Y B
IH : forall X R T S,
is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S
IsX : is_string X
IsR : is_tm R
S : X = Y -> false
S1 : subst X R B S1 *
Is : is_string Y
Is1 : is_ty Ty
Is2 : is_tm B
H1 : is_tm S1
============================
is_tm (abs Y Ty S1)
< search.
Subgoal 4:
Variables: X R B Ty
IH : forall X R T S,
is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S
IsT : is_tm (abs X Ty B)
IsX : is_string X
IsR : is_tm R
============================
is_tm (abs X Ty B)
< search.
Subgoal 5:
Variables: X R S2 S1 T2 T1
IH : forall X R T S,
is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S
IsT : is_tm (app T1 T2)
IsX : is_string X
IsR : is_tm R
S : subst X R T1 S1 *
S1 : subst X R T2 S2 *
============================
is_tm (app S1 S2)
< Is: case IsT.
Subgoal 5:
Variables: X R S2 S1 T2 T1
IH : forall X R T S,
is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S
IsX : is_string X
IsR : is_tm R
S : subst X R T1 S1 *
S1 : subst X R T2 S2 *
Is : is_tm T1
Is1 : is_tm T2
============================
is_tm (app S1 S2)
< apply IH to _ _ _ S.
Subgoal 5:
Variables: X R S2 S1 T2 T1
IH : forall X R T S,
is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S
IsX : is_string X
IsR : is_tm R
S : subst X R T1 S1 *
S1 : subst X R T2 S2 *
Is : is_tm T1
Is1 : is_tm T2
H1 : is_tm S1
============================
is_tm (app S1 S2)
< apply IH to _ _ _ S1.
Subgoal 5:
Variables: X R S2 S1 T2 T1
IH : forall X R T S,
is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S
IsX : is_string X
IsR : is_tm R
S : subst X R T1 S1 *
S1 : subst X R T2 S2 *
Is : is_tm T1
Is1 : is_tm T2
H1 : is_tm S1
H2 : is_tm S2
============================
is_tm (app S1 S2)
< search.
Subgoal 6:
Variables: X R I
IH : forall X R T S,
is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S
IsT : is_tm (num I)
IsX : is_string X
IsR : is_tm R
============================
is_tm (num I)
< search.
Subgoal 7:
Variables: X R S2 S1 T2 T1
IH : forall X R T S,
is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S
IsT : is_tm (plus T1 T2)
IsX : is_string X
IsR : is_tm R
S : subst X R T1 S1 *
S1 : subst X R T2 S2 *
============================
is_tm (plus S1 S2)
< Is: case IsT.
Subgoal 7:
Variables: X R S2 S1 T2 T1
IH : forall X R T S,
is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S
IsX : is_string X
IsR : is_tm R
S : subst X R T1 S1 *
S1 : subst X R T2 S2 *
Is : is_tm T1
Is1 : is_tm T2
============================
is_tm (plus S1 S2)
< apply IH to _ _ _ S.
Subgoal 7:
Variables: X R S2 S1 T2 T1
IH : forall X R T S,
is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S
IsX : is_string X
IsR : is_tm R
S : subst X R T1 S1 *
S1 : subst X R T2 S2 *
Is : is_tm T1
Is1 : is_tm T2
H1 : is_tm S1
============================
is_tm (plus S1 S2)
< apply IH to _ _ _ S1.
Subgoal 7:
Variables: X R S2 S1 T2 T1
IH : forall X R T S,
is_tm T -> is_string X -> is_tm R -> subst X R T S * -> is_tm S
IsX : is_string X
IsR : is_tm R
S : subst X R T1 S1 *
S1 : subst X R T2 S2 *
Is : is_tm T1
Is1 : is_tm T2
H1 : is_tm S1
H2 : is_tm S2
============================
is_tm (plus S1 S2)
< search.
Proof completed.
< Theorem eval_is :
forall T T', is_tm T -> eval T T' -> is_tm T'.
============================
forall T T', is_tm T -> eval T T' -> is_tm T'
< induction on 2.
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
============================
forall T T', is_tm T -> eval T T' @ -> is_tm T'
< intros IsT Ev.
Variables: T T'
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
IsT : is_tm T
Ev : eval T T' @
============================
is_tm T'
< Ev: case Ev.
Subgoal 1:
Variables: T2 T11 T1
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
IsT : is_tm (app T1 T2)
Ev : eval T1 T11 *
============================
is_tm (app T11 T2)
< Is: case IsT.
Subgoal 1:
Variables: T2 T11 T1
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
Ev : eval T1 T11 *
Is : is_tm T1
Is1 : is_tm T2
============================
is_tm (app T11 T2)
< apply IH to _ Ev.
Subgoal 1:
Variables: T2 T11 T1
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
Ev : eval T1 T11 *
Is : is_tm T1
Is1 : is_tm T2
H1 : is_tm T11
============================
is_tm (app T11 T2)
< search.
Subgoal 2:
Variables: T21 T1 T2
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
IsT : is_tm (app T1 T2)
Ev : value T1
Ev1 : eval T2 T21 *
============================
is_tm (app T1 T21)
< Is: case IsT.
Subgoal 2:
Variables: T21 T1 T2
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
Ev : value T1
Ev1 : eval T2 T21 *
Is : is_tm T1
Is1 : is_tm T2
============================
is_tm (app T1 T21)
< apply IH to _ Ev1.
Subgoal 2:
Variables: T21 T1 T2
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
Ev : value T1
Ev1 : eval T2 T21 *
Is : is_tm T1
Is1 : is_tm T2
H1 : is_tm T21
============================
is_tm (app T1 T21)
< search.
Subgoal 3:
Variables: T' T2 Body Ty X
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
IsT : is_tm (app (abs X Ty Body) T2)
Ev : value T2
Ev1 : subst X T2 Body T'
============================
is_tm T'
< Is: case IsT.
Subgoal 3:
Variables: T' T2 Body Ty X
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
Ev : value T2
Ev1 : subst X T2 Body T'
Is : is_tm (abs X Ty Body)
Is1 : is_tm T2
============================
is_tm T'
< case Is.
Subgoal 3:
Variables: T' T2 Body Ty X
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
Ev : value T2
Ev1 : subst X T2 Body T'
Is1 : is_tm T2
H1 : is_string X
H2 : is_ty Ty
H3 : is_tm Body
============================
is_tm T'
< apply subst_is to _ _ _ Ev1.
Subgoal 3:
Variables: T' T2 Body Ty X
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
Ev : value T2
Ev1 : subst X T2 Body T'
Is1 : is_tm T2
H1 : is_string X
H2 : is_ty Ty
H3 : is_tm Body
H4 : is_tm T'
============================
is_tm T'
< search.
Subgoal 4:
Variables: T2 T11 T1
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
IsT : is_tm (plus T1 T2)
Ev : eval T1 T11 *
============================
is_tm (plus T11 T2)
< Is: case IsT.
Subgoal 4:
Variables: T2 T11 T1
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
Ev : eval T1 T11 *
Is : is_tm T1
Is1 : is_tm T2
============================
is_tm (plus T11 T2)
< apply IH to _ Ev.
Subgoal 4:
Variables: T2 T11 T1
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
Ev : eval T1 T11 *
Is : is_tm T1
Is1 : is_tm T2
H1 : is_tm T11
============================
is_tm (plus T11 T2)
< search.
Subgoal 5:
Variables: T21 T1 T2
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
IsT : is_tm (plus T1 T2)
Ev : value T1
Ev1 : eval T2 T21 *
============================
is_tm (plus T1 T21)
< Is: case IsT.
Subgoal 5:
Variables: T21 T1 T2
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
Ev : value T1
Ev1 : eval T2 T21 *
Is : is_tm T1
Is1 : is_tm T2
============================
is_tm (plus T1 T21)
< apply IH to _ Ev1.
Subgoal 5:
Variables: T21 T1 T2
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
Ev : value T1
Ev1 : eval T2 T21 *
Is : is_tm T1
Is1 : is_tm T2
H1 : is_tm T21
============================
is_tm (plus T1 T21)
< search.
Subgoal 6:
Variables: I I2 I1
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
IsT : is_tm (plus (num I1) (num I2))
Ev : I1 + I2 = I
============================
is_tm (num I)
< Is: case IsT.
Subgoal 6:
Variables: I I2 I1
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
Ev : I1 + I2 = I
Is : is_tm (num I1)
Is1 : is_tm (num I2)
============================
is_tm (num I)
< case Is.
Subgoal 6:
Variables: I I2 I1
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
Ev : I1 + I2 = I
Is1 : is_tm (num I2)
H1 : is_integer I1
============================
is_tm (num I)
< case Is1.
Subgoal 6:
Variables: I I2 I1
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
Ev : I1 + I2 = I
H1 : is_integer I1
H2 : is_integer I2
============================
is_tm (num I)
< apply plus_integer_is_integer to _ _ Ev.
Subgoal 6:
Variables: I I2 I1
IH : forall T T', is_tm T -> eval T T' * -> is_tm T'
Ev : I1 + I2 = I
H1 : is_integer I1
H2 : is_integer I2
H3 : is_integer I
============================
is_tm (num I)
< search.
Proof completed.
< Theorem subst_unique :
forall X R T VA VB, subst X R T VA -> subst X R T VB -> VA = VB.
============================
forall X R T VA VB, subst X R T VA -> subst X R T VB -> VA = VB
< induction on 1.
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
============================
forall X R T VA VB, subst X R T VA @ -> subst X R T VB -> VA = VB
< intros SA SB.
Variables: X R T VA VB
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SA : subst X R T VA @
SB : subst X R T VB
============================
VA = VB
< SA: case SA.
Subgoal 1:
Variables: X R VB Y
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SB : subst X R (var Y) VB
SA : X = Y -> false
============================
var Y = VB
< SB: case SB.
Subgoal 1.1:
Variables: X R Y
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SA : X = Y -> false
SB : X = Y -> false
============================
var Y = var Y
< search.
Subgoal 1.2:
Variables: VB Y
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SA : Y = Y -> false
============================
var Y = VB
< apply SA to _.
Subgoal 2:
Variables: X VA VB
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SB : subst X VA (var X) VB
============================
VA = VB
< SB: case SB.
Subgoal 2.1:
Variables: X VA
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SB : X = X -> false
============================
VA = var X
< apply SB to _.
Subgoal 2.2:
Variables: X VB
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
============================
VB = VB
< search.
Subgoal 3:
Variables: X R VB S Ty Y B
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SB : subst X R (abs Y Ty B) VB
SA : X = Y -> false
SA1 : subst X R B S *
============================
abs Y Ty S = VB
< SB: case SB.
Subgoal 3.1:
Variables: X R S Ty Y B S1
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SA : X = Y -> false
SA1 : subst X R B S *
SB : X = Y -> false
SB1 : subst X R B S1
============================
abs Y Ty S = abs Y Ty S1
< apply IH to SA1 SB1.
Subgoal 3.1:
Variables: X R Ty Y B S1
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SA : X = Y -> false
SA1 : subst X R B S1 *
SB : X = Y -> false
SB1 : subst X R B S1
============================
abs Y Ty S1 = abs Y Ty S1
< search.
Subgoal 3.2:
Variables: R S Ty Y B
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SA : Y = Y -> false
SA1 : subst Y R B S *
============================
abs Y Ty S = abs Y Ty B
< apply SA to _.
Subgoal 4:
Variables: X R VB B Ty
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SB : subst X R (abs X Ty B) VB
============================
abs X Ty B = VB
< SB: case SB.
Subgoal 4.1:
Variables: X R B Ty S
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SB : X = X -> false
SB1 : subst X R B S
============================
abs X Ty B = abs X Ty S
< apply SB to _.
Subgoal 4.2:
Variables: X R B Ty
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
============================
abs X Ty B = abs X Ty B
< search.
Subgoal 5:
Variables: X R VB S2 S1 T2 T1
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SB : subst X R (app T1 T2) VB
SA : subst X R T1 S1 *
SA1 : subst X R T2 S2 *
============================
app S1 S2 = VB
< SB: case SB.
Subgoal 5:
Variables: X R S2 S1 T2 T1 S4 S3
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SA : subst X R T1 S1 *
SA1 : subst X R T2 S2 *
SB : subst X R T1 S3
SB1 : subst X R T2 S4
============================
app S1 S2 = app S3 S4
< apply IH to SA SB.
Subgoal 5:
Variables: X R S2 T2 T1 S4 S3
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SA : subst X R T1 S3 *
SA1 : subst X R T2 S2 *
SB : subst X R T1 S3
SB1 : subst X R T2 S4
============================
app S3 S2 = app S3 S4
< apply IH to SA1 SB1.
Subgoal 5:
Variables: X R T2 T1 S4 S3
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SA : subst X R T1 S3 *
SA1 : subst X R T2 S4 *
SB : subst X R T1 S3
SB1 : subst X R T2 S4
============================
app S3 S4 = app S3 S4
< search.
Subgoal 6:
Variables: X R VB I
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SB : subst X R (num I) VB
============================
num I = VB
< SB: case SB.
Subgoal 6:
Variables: X R I
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
============================
num I = num I
< search.
Subgoal 7:
Variables: X R VB S2 S1 T2 T1
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SB : subst X R (plus T1 T2) VB
SA : subst X R T1 S1 *
SA1 : subst X R T2 S2 *
============================
plus S1 S2 = VB
< SB: case SB.
Subgoal 7:
Variables: X R S2 S1 T2 T1 S4 S3
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SA : subst X R T1 S1 *
SA1 : subst X R T2 S2 *
SB : subst X R T1 S3
SB1 : subst X R T2 S4
============================
plus S1 S2 = plus S3 S4
< apply IH to SA SB.
Subgoal 7:
Variables: X R S2 T2 T1 S4 S3
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SA : subst X R T1 S3 *
SA1 : subst X R T2 S2 *
SB : subst X R T1 S3
SB1 : subst X R T2 S4
============================
plus S3 S2 = plus S3 S4
< apply IH to SA1 SB1.
Subgoal 7:
Variables: X R T2 T1 S4 S3
IH : forall X R T VA VB, subst X R T VA * -> subst X R T VB -> VA = VB
SA : subst X R T1 S3 *
SA1 : subst X R T2 S4 *
SB : subst X R T1 S3
SB1 : subst X R T2 S4
============================
plus S3 S4 = plus S3 S4
< search.
Proof completed.
< Theorem value_eval_false :
forall T V, value T -> eval T V -> false.
============================
forall T V, value T -> eval T V -> false
< intros V Ev.
Variables: T V
V : value T
Ev : eval T V
============================
false
< V: case V.
Subgoal 1:
Variables: V T1 Ty X
Ev : eval (abs X Ty T1) V
============================
false
< case Ev.
Subgoal 2:
Variables: V I
Ev : eval (num I) V
============================
false
< case Ev.
Proof completed.
< Theorem eval_unique :
forall T VA VB, eval T VA -> eval T VB -> VA = VB.
============================
forall T VA VB, eval T VA -> eval T VB -> VA = VB
< induction on 1.
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
============================
forall T VA VB, eval T VA @ -> eval T VB -> VA = VB
< intros EvA EvB.
Variables: T VA VB
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : eval T VA @
EvB : eval T VB
============================
VA = VB
< EvA: case EvA.
Subgoal 1:
Variables: VB T2 T11 T1
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvB : eval (app T1 T2) VB
EvA : eval T1 T11 *
============================
app T11 T2 = VB
< EvB: case EvB.
Subgoal 1.1:
Variables: T2 T11 T1 T5
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : eval T1 T11 *
EvB : eval T1 T5
============================
app T11 T2 = app T5 T2
< apply IH to EvA EvB.
Subgoal 1.1:
Variables: T2 T1 T5
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : eval T1 T5 *
EvB : eval T1 T5
============================
app T5 T2 = app T5 T2
< search.
Subgoal 1.2:
Variables: T2 T11 T1 T21
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : eval T1 T11 *
EvB : value T1
EvB1 : eval T2 T21
============================
app T11 T2 = app T1 T21
< apply value_eval_false to EvB EvA.
Subgoal 1.3:
Variables: VB T2 T11 Body Ty X
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : eval (abs X Ty Body) T11 *
EvB : value T2
EvB1 : subst X T2 Body VB
============================
app T11 T2 = VB
< apply value_eval_false to _ EvA.
Subgoal 2:
Variables: VB T21 T1 T2
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvB : eval (app T1 T2) VB
EvA : value T1
EvA1 : eval T2 T21 *
============================
app T1 T21 = VB
< EvB: case EvB.
Subgoal 2.1:
Variables: T21 T1 T2 T11
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : value T1
EvA1 : eval T2 T21 *
EvB : eval T1 T11
============================
app T1 T21 = app T11 T2
< apply value_eval_false to EvA EvB.
Subgoal 2.2:
Variables: T21 T1 T2 T5
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : value T1
EvA1 : eval T2 T21 *
EvB : value T1
EvB1 : eval T2 T5
============================
app T1 T21 = app T1 T5
< apply IH to EvA1 EvB1.
Subgoal 2.2:
Variables: T1 T2 T5
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : value T1
EvA1 : eval T2 T5 *
EvB : value T1
EvB1 : eval T2 T5
============================
app T1 T5 = app T1 T5
< search.
Subgoal 2.3:
Variables: VB T21 T2 Body Ty X
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : value (abs X Ty Body)
EvA1 : eval T2 T21 *
EvB : value T2
EvB1 : subst X T2 Body VB
============================
app (abs X Ty Body) T21 = VB
< apply value_eval_false to EvB EvA1.
Subgoal 3:
Variables: VA VB T2 Body Ty X
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvB : eval (app (abs X Ty Body) T2) VB
EvA : value T2
EvA1 : subst X T2 Body VA
============================
VA = VB
< EvB: case EvB.
Subgoal 3.1:
Variables: VA T2 Body Ty X T11
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : value T2
EvA1 : subst X T2 Body VA
EvB : eval (abs X Ty Body) T11
============================
VA = app T11 T2
< case EvB.
Subgoal 3.2:
Variables: VA T2 Body Ty X T21
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : value T2
EvA1 : subst X T2 Body VA
EvB : value (abs X Ty Body)
EvB1 : eval T2 T21
============================
VA = app (abs X Ty Body) T21
< apply value_eval_false to EvA EvB1.
Subgoal 3.3:
Variables: VA VB T2 Body Ty X
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : value T2
EvA1 : subst X T2 Body VA
EvB : value T2
EvB1 : subst X T2 Body VB
============================
VA = VB
< apply subst_unique to EvA1 EvB1.
Subgoal 3.3:
Variables: VB T2 Body Ty X
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : value T2
EvA1 : subst X T2 Body VB
EvB : value T2
EvB1 : subst X T2 Body VB
============================
VB = VB
< search.
Subgoal 4:
Variables: VB T2 T11 T1
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvB : eval (plus T1 T2) VB
EvA : eval T1 T11 *
============================
plus T11 T2 = VB
< EvB: case EvB.
Subgoal 4.1:
Variables: T2 T11 T1 T5
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : eval T1 T11 *
EvB : eval T1 T5
============================
plus T11 T2 = plus T5 T2
< apply IH to EvA EvB.
Subgoal 4.1:
Variables: T2 T1 T5
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : eval T1 T5 *
EvB : eval T1 T5
============================
plus T5 T2 = plus T5 T2
< search.
Subgoal 4.2:
Variables: T2 T11 T1 T21
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : eval T1 T11 *
EvB : value T1
EvB1 : eval T2 T21
============================
plus T11 T2 = plus T1 T21
< apply value_eval_false to EvB EvA.
Subgoal 4.3:
Variables: T11 I I2 I1
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : eval (num I1) T11 *
EvB : I1 + I2 = I
============================
plus T11 (num I2) = num I
< case EvA.
Subgoal 5:
Variables: VB T21 T1 T2
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvB : eval (plus T1 T2) VB
EvA : value T1
EvA1 : eval T2 T21 *
============================
plus T1 T21 = VB
< EvB: case EvB.
Subgoal 5.1:
Variables: T21 T1 T2 T11
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : value T1
EvA1 : eval T2 T21 *
EvB : eval T1 T11
============================
plus T1 T21 = plus T11 T2
< apply value_eval_false to EvA EvB.
Subgoal 5.2:
Variables: T21 T1 T2 T5
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : value T1
EvA1 : eval T2 T21 *
EvB : value T1
EvB1 : eval T2 T5
============================
plus T1 T21 = plus T1 T5
< apply IH to EvA1 EvB1.
Subgoal 5.2:
Variables: T1 T2 T5
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : value T1
EvA1 : eval T2 T5 *
EvB : value T1
EvB1 : eval T2 T5
============================
plus T1 T5 = plus T1 T5
< search.
Subgoal 5.3:
Variables: T21 I I2 I1
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : value (num I1)
EvA1 : eval (num I2) T21 *
EvB : I1 + I2 = I
============================
plus (num I1) T21 = num I
< case EvA1.
Subgoal 6:
Variables: VB I I2 I1
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvB : eval (plus (num I1) (num I2)) VB
EvA : I1 + I2 = I
============================
num I = VB
< EvB: case EvB.
Subgoal 6.1:
Variables: I I2 I1 T11
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : I1 + I2 = I
EvB : eval (num I1) T11
============================
num I = plus T11 (num I2)
< case EvB.
Subgoal 6.2:
Variables: I I2 I1 T21
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : I1 + I2 = I
EvB : value (num I1)
EvB1 : eval (num I2) T21
============================
num I = plus (num I1) T21
< case EvB1.
Subgoal 6.3:
Variables: I I2 I1 I5
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : I1 + I2 = I
EvB : I1 + I2 = I5
============================
num I = num I5
< apply plus_integer_unique to EvA EvB.
Subgoal 6.3:
Variables: I2 I1 I5
IH : forall T VA VB, eval T VA * -> eval T VB -> VA = VB
EvA : I1 + I2 = I5
EvB : I1 + I2 = I5
============================
num I5 = num I5
< search.
Proof completed.
< Theorem subst_type_preservation :
forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S -> typeOf [] R XTy -> typeOf Ctx S Ty.
============================
forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S -> typeOf [] R XTy -> typeOf Ctx S Ty
< induction on 2.
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
============================
forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S @ -> typeOf [] R XTy -> typeOf Ctx S Ty
< intros TTy S RTy.
Variables: T Ctx X XTy Ty R S
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
TTy : typeOf ((X, XTy)::Ctx) T Ty
S : subst X R T S @
RTy : typeOf [] R XTy
============================
typeOf Ctx S Ty
< S: case S.
Subgoal 1:
Variables: Ctx X XTy Ty R Y
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
TTy : typeOf ((X, XTy)::Ctx) (var Y) Ty
RTy : typeOf [] R XTy
S : X = Y -> false
============================
typeOf Ctx (var Y) Ty
< Ty: case TTy.
Subgoal 1:
Variables: Ctx X XTy Ty R Y
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
S : X = Y -> false
Ty : lookup ((X, XTy)::Ctx) Y Ty
============================
typeOf Ctx (var Y) Ty
< Lkp: case Ty.
Subgoal 1.1:
Variables: Ctx Ty R Y
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R Ty
S : Y = Y -> false
============================
typeOf Ctx (var Y) Ty
< apply S to _.
Subgoal 1.2:
Variables: Ctx X XTy Ty R Y
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
S : X = Y -> false
Lkp : X = Y -> false
Lkp1 : lookup Ctx Y Ty
============================
typeOf Ctx (var Y) Ty
< search.
Subgoal 2:
Variables: Ctx X XTy Ty S
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
TTy : typeOf ((X, XTy)::Ctx) (var X) Ty
RTy : typeOf [] S XTy
============================
typeOf Ctx S Ty
< Ty: case TTy.
Subgoal 2:
Variables: Ctx X XTy Ty S
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] S XTy
Ty : lookup ((X, XTy)::Ctx) X Ty
============================
typeOf Ctx S Ty
< L: case Ty.
Subgoal 2.1:
Variables: Ctx X Ty S
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] S Ty
============================
typeOf Ctx S Ty
< backchain empty_ty_any.
Subgoal 2.2:
Variables: Ctx X XTy Ty S
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] S XTy
L : X = X -> false
L1 : lookup Ctx X Ty
============================
typeOf Ctx S Ty
< apply L to _.
Subgoal 3:
Variables: Ctx X XTy Ty R S1 Ty1 Y B
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
TTy : typeOf ((X, XTy)::Ctx) (abs Y Ty1 B) Ty
RTy : typeOf [] R XTy
S : X = Y -> false
S1 : subst X R B S1 *
============================
typeOf Ctx (abs Y Ty1 S1) Ty
< Ty: case TTy.
Subgoal 3:
Variables: Ctx X XTy R S1 Ty1 Y B Ty3
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
S : X = Y -> false
S1 : subst X R B S1 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) B Ty3
============================
typeOf Ctx (abs Y Ty1 S1) (arrowTy Ty1 Ty3)
< Ty': apply ty_lookup to Ty _ with
Ctx2 = (X, XTy)::((Y, Ty1)::Ctx).
Subgoal 3.1:
Variables: Ctx X XTy R S1 Ty1 Y B Ty3
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
S : X = Y -> false
S1 : subst X R B S1 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) B Ty3
============================
forall X1 XTy1,
lookup ((Y, Ty1)::((X, XTy)::Ctx)) X1 XTy1 -> lookup ((X, XTy)::((Y, Ty1)::Ctx)) X1 XTy1
< intros L.
Subgoal 3.1:
Variables: Ctx X XTy R S1 Ty1 Y B Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
S : X = Y -> false
S1 : subst X R B S1 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) B Ty3
L : lookup ((Y, Ty1)::((X, XTy)::Ctx)) X1 XTy1
============================
lookup ((X, XTy)::((Y, Ty1)::Ctx)) X1 XTy1
< L: case L.
Subgoal 3.1.1:
Variables: Ctx X XTy R S1 B Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
S : X = X1 -> false
S1 : subst X R B S1 *
Ty : typeOf ((X1, XTy1)::((X, XTy)::Ctx)) B Ty3
============================
lookup ((X, XTy)::((X1, XTy1)::Ctx)) X1 XTy1
< search.
Subgoal 3.1.2:
Variables: Ctx X XTy R S1 Ty1 Y B Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
S : X = Y -> false
S1 : subst X R B S1 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) B Ty3
L : Y = X1 -> false
L1 : lookup ((X, XTy)::Ctx) X1 XTy1
============================
lookup ((X, XTy)::((Y, Ty1)::Ctx)) X1 XTy1
< L: case L1.
Subgoal 3.1.2.1:
Variables: Ctx R S1 Ty1 Y B Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy1
S : X1 = Y -> false
S1 : subst X1 R B S1 *
Ty : typeOf ((Y, Ty1)::((X1, XTy1)::Ctx)) B Ty3
L : Y = X1 -> false
============================
lookup ((X1, XTy1)::((Y, Ty1)::Ctx)) X1 XTy1
< search.
Subgoal 3.1.2.2:
Variables: Ctx X XTy R S1 Ty1 Y B Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
S : X = Y -> false
S1 : subst X R B S1 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) B Ty3
L : Y = X1 -> false
L1 : X = X1 -> false
L2 : lookup Ctx X1 XTy1
============================
lookup ((X, XTy)::((Y, Ty1)::Ctx)) X1 XTy1
< search.
Subgoal 3:
Variables: Ctx X XTy R S1 Ty1 Y B Ty3
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
S : X = Y -> false
S1 : subst X R B S1 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) B Ty3
Ty' : typeOf ((X, XTy)::((Y, Ty1)::Ctx)) B Ty3
============================
typeOf Ctx (abs Y Ty1 S1) (arrowTy Ty1 Ty3)
< apply IH to Ty' S1 _.
Subgoal 3:
Variables: Ctx X XTy R S1 Ty1 Y B Ty3
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
S : X = Y -> false
S1 : subst X R B S1 *
Ty : typeOf ((Y, Ty1)::((X, XTy)::Ctx)) B Ty3
Ty' : typeOf ((X, XTy)::((Y, Ty1)::Ctx)) B Ty3
H1 : typeOf ((Y, Ty1)::Ctx) S1 Ty3
============================
typeOf Ctx (abs Y Ty1 S1) (arrowTy Ty1 Ty3)
< search.
Subgoal 4:
Variables: Ctx X XTy Ty R B Ty1
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
TTy : typeOf ((X, XTy)::Ctx) (abs X Ty1 B) Ty
RTy : typeOf [] R XTy
============================
typeOf Ctx (abs X Ty1 B) Ty
< Ty: case TTy.
Subgoal 4:
Variables: Ctx X XTy R B Ty1 Ty3
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
Ty : typeOf ((X, Ty1)::((X, XTy)::Ctx)) B Ty3
============================
typeOf Ctx (abs X Ty1 B) (arrowTy Ty1 Ty3)
< apply ty_lookup to Ty _ with
Ctx2 = (X, Ty1)::Ctx.
Subgoal 4.1:
Variables: Ctx X XTy R B Ty1 Ty3
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
Ty : typeOf ((X, Ty1)::((X, XTy)::Ctx)) B Ty3
============================
forall X1 XTy1,
lookup ((X, Ty1)::((X, XTy)::Ctx)) X1 XTy1 -> lookup ((X, Ty1)::Ctx) X1 XTy1
< intros L.
Subgoal 4.1:
Variables: Ctx X XTy R B Ty1 Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
Ty : typeOf ((X, Ty1)::((X, XTy)::Ctx)) B Ty3
L : lookup ((X, Ty1)::((X, XTy)::Ctx)) X1 XTy1
============================
lookup ((X, Ty1)::Ctx) X1 XTy1
< L: case L.
Subgoal 4.1.1:
Variables: Ctx XTy R B Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
Ty : typeOf ((X1, XTy1)::((X1, XTy)::Ctx)) B Ty3
============================
lookup ((X1, XTy1)::Ctx) X1 XTy1
< search.
Subgoal 4.1.2:
Variables: Ctx X XTy R B Ty1 Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
Ty : typeOf ((X, Ty1)::((X, XTy)::Ctx)) B Ty3
L : X = X1 -> false
L1 : lookup ((X, XTy)::Ctx) X1 XTy1
============================
lookup ((X, Ty1)::Ctx) X1 XTy1
< L: case L1.
Subgoal 4.1.2.1:
Variables: Ctx R B Ty1 Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy1
Ty : typeOf ((X1, Ty1)::((X1, XTy1)::Ctx)) B Ty3
L : X1 = X1 -> false
============================
lookup ((X1, Ty1)::Ctx) X1 XTy1
< apply L to _.
Subgoal 4.1.2.2:
Variables: Ctx X XTy R B Ty1 Ty3 X1 XTy1
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
Ty : typeOf ((X, Ty1)::((X, XTy)::Ctx)) B Ty3
L : X = X1 -> false
L1 : X = X1 -> false
L2 : lookup Ctx X1 XTy1
============================
lookup ((X, Ty1)::Ctx) X1 XTy1
< search.
Subgoal 4:
Variables: Ctx X XTy R B Ty1 Ty3
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
Ty : typeOf ((X, Ty1)::((X, XTy)::Ctx)) B Ty3
H1 : typeOf ((X, Ty1)::Ctx) B Ty3
============================
typeOf Ctx (abs X Ty1 B) (arrowTy Ty1 Ty3)
< search.
Subgoal 5:
Variables: Ctx X XTy Ty R S2 S1 T2 T1
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
TTy : typeOf ((X, XTy)::Ctx) (app T1 T2) Ty
RTy : typeOf [] R XTy
S : subst X R T1 S1 *
S1 : subst X R T2 S2 *
============================
typeOf Ctx (app S1 S2) Ty
< Ty: case TTy.
Subgoal 5:
Variables: Ctx X XTy Ty R S2 S1 T2 T1 Ty1
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
S : subst X R T1 S1 *
S1 : subst X R T2 S2 *
Ty : typeOf ((X, XTy)::Ctx) T1 (arrowTy Ty1 Ty)
Ty1 : typeOf ((X, XTy)::Ctx) T2 Ty1
============================
typeOf Ctx (app S1 S2) Ty
< apply IH to Ty S _.
Subgoal 5:
Variables: Ctx X XTy Ty R S2 S1 T2 T1 Ty1
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
S : subst X R T1 S1 *
S1 : subst X R T2 S2 *
Ty : typeOf ((X, XTy)::Ctx) T1 (arrowTy Ty1 Ty)
Ty1 : typeOf ((X, XTy)::Ctx) T2 Ty1
H1 : typeOf Ctx S1 (arrowTy Ty1 Ty)
============================
typeOf Ctx (app S1 S2) Ty
< apply IH to Ty1 S1 _.
Subgoal 5:
Variables: Ctx X XTy Ty R S2 S1 T2 T1 Ty1
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
S : subst X R T1 S1 *
S1 : subst X R T2 S2 *
Ty : typeOf ((X, XTy)::Ctx) T1 (arrowTy Ty1 Ty)
Ty1 : typeOf ((X, XTy)::Ctx) T2 Ty1
H1 : typeOf Ctx S1 (arrowTy Ty1 Ty)
H2 : typeOf Ctx S2 Ty1
============================
typeOf Ctx (app S1 S2) Ty
< search.
Subgoal 6:
Variables: Ctx X XTy Ty R I
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
TTy : typeOf ((X, XTy)::Ctx) (num I) Ty
RTy : typeOf [] R XTy
============================
typeOf Ctx (num I) Ty
< case TTy.
Subgoal 6:
Variables: Ctx X XTy R I
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
============================
typeOf Ctx (num I) intTy
< search.
Subgoal 7:
Variables: Ctx X XTy Ty R S2 S1 T2 T1
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
TTy : typeOf ((X, XTy)::Ctx) (plus T1 T2) Ty
RTy : typeOf [] R XTy
S : subst X R T1 S1 *
S1 : subst X R T2 S2 *
============================
typeOf Ctx (plus S1 S2) Ty
< Ty: case TTy.
Subgoal 7:
Variables: Ctx X XTy R S2 S1 T2 T1
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
S : subst X R T1 S1 *
S1 : subst X R T2 S2 *
Ty : typeOf ((X, XTy)::Ctx) T1 intTy
Ty1 : typeOf ((X, XTy)::Ctx) T2 intTy
============================
typeOf Ctx (plus S1 S2) intTy
< apply IH to Ty S _.
Subgoal 7:
Variables: Ctx X XTy R S2 S1 T2 T1
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
S : subst X R T1 S1 *
S1 : subst X R T2 S2 *
Ty : typeOf ((X, XTy)::Ctx) T1 intTy
Ty1 : typeOf ((X, XTy)::Ctx) T2 intTy
H1 : typeOf Ctx S1 intTy
============================
typeOf Ctx (plus S1 S2) intTy
< apply IH to Ty1 S1 _.
Subgoal 7:
Variables: Ctx X XTy R S2 S1 T2 T1
IH : forall T Ctx X XTy Ty R S,
typeOf ((X, XTy)::Ctx) T Ty -> subst X R T S * -> typeOf [] R XTy -> typeOf Ctx S Ty
RTy : typeOf [] R XTy
S : subst X R T1 S1 *
S1 : subst X R T2 S2 *
Ty : typeOf ((X, XTy)::Ctx) T1 intTy
Ty1 : typeOf ((X, XTy)::Ctx) T2 intTy
H1 : typeOf Ctx S1 intTy
H2 : typeOf Ctx S2 intTy
============================
typeOf Ctx (plus S1 S2) intTy
< search.
Proof completed.
< Theorem type_preservation :
forall T Ty T', typeOf [] T Ty -> eval T T' -> typeOf [] T' Ty.
============================
forall T Ty T', typeOf [] T Ty -> eval T T' -> typeOf [] T' Ty
< induction on 2.
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
============================
forall T Ty T', typeOf [] T Ty -> eval T T' @ -> typeOf [] T' Ty
< intros Ty Ev.
Variables: T Ty T'
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ty : typeOf [] T Ty
Ev : eval T T' @
============================
typeOf [] T' Ty
< Ev: case Ev.
Subgoal 1:
Variables: Ty T2 T11 T1
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ty : typeOf [] (app T1 T2) Ty
Ev : eval T1 T11 *
============================
typeOf [] (app T11 T2) Ty
< Ty: case Ty.
Subgoal 1:
Variables: Ty T2 T11 T1 Ty1
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ev : eval T1 T11 *
Ty : typeOf [] T1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] T2 Ty1
============================
typeOf [] (app T11 T2) Ty
< apply IH to Ty Ev.
Subgoal 1:
Variables: Ty T2 T11 T1 Ty1
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ev : eval T1 T11 *
Ty : typeOf [] T1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] T2 Ty1
H1 : typeOf [] T11 (arrowTy Ty1 Ty)
============================
typeOf [] (app T11 T2) Ty
< search.
Subgoal 2:
Variables: Ty T21 T1 T2
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ty : typeOf [] (app T1 T2) Ty
Ev : value T1
Ev1 : eval T2 T21 *
============================
typeOf [] (app T1 T21) Ty
< Ty: case Ty.
Subgoal 2:
Variables: Ty T21 T1 T2 Ty1
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ev : value T1
Ev1 : eval T2 T21 *
Ty : typeOf [] T1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] T2 Ty1
============================
typeOf [] (app T1 T21) Ty
< apply IH to Ty1 Ev1.
Subgoal 2:
Variables: Ty T21 T1 T2 Ty1
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ev : value T1
Ev1 : eval T2 T21 *
Ty : typeOf [] T1 (arrowTy Ty1 Ty)
Ty1 : typeOf [] T2 Ty1
H1 : typeOf [] T21 Ty1
============================
typeOf [] (app T1 T21) Ty
< search.
Subgoal 3:
Variables: Ty T' T2 Body Ty1 X
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ty : typeOf [] (app (abs X Ty1 Body) T2) Ty
Ev : value T2
Ev1 : subst X T2 Body T'
============================
typeOf [] T' Ty
< Ty: case Ty.
Subgoal 3:
Variables: Ty T' T2 Body Ty1 X Ty2
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ev : value T2
Ev1 : subst X T2 Body T'
Ty : typeOf [] (abs X Ty1 Body) (arrowTy Ty2 Ty)
Ty1 : typeOf [] T2 Ty2
============================
typeOf [] T' Ty
< Ty: case Ty.
Subgoal 3:
Variables: Ty T' T2 Body X Ty2
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ev : value T2
Ev1 : subst X T2 Body T'
Ty1 : typeOf [] T2 Ty2
Ty : typeOf [(X, Ty2)] Body Ty
============================
typeOf [] T' Ty
< apply subst_type_preservation to Ty Ev1 Ty1.
Subgoal 3:
Variables: Ty T' T2 Body X Ty2
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ev : value T2
Ev1 : subst X T2 Body T'
Ty1 : typeOf [] T2 Ty2
Ty : typeOf [(X, Ty2)] Body Ty
H1 : typeOf [] T' Ty
============================
typeOf [] T' Ty
< search.
Subgoal 4:
Variables: Ty T2 T11 T1
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ty : typeOf [] (plus T1 T2) Ty
Ev : eval T1 T11 *
============================
typeOf [] (plus T11 T2) Ty
< Ty: case Ty.
Subgoal 4:
Variables: T2 T11 T1
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ev : eval T1 T11 *
Ty : typeOf [] T1 intTy
Ty1 : typeOf [] T2 intTy
============================
typeOf [] (plus T11 T2) intTy
< apply IH to Ty Ev.
Subgoal 4:
Variables: T2 T11 T1
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ev : eval T1 T11 *
Ty : typeOf [] T1 intTy
Ty1 : typeOf [] T2 intTy
H1 : typeOf [] T11 intTy
============================
typeOf [] (plus T11 T2) intTy
< search.
Subgoal 5:
Variables: Ty T21 T1 T2
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ty : typeOf [] (plus T1 T2) Ty
Ev : value T1
Ev1 : eval T2 T21 *
============================
typeOf [] (plus T1 T21) Ty
< Ty: case Ty.
Subgoal 5:
Variables: T21 T1 T2
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ev : value T1
Ev1 : eval T2 T21 *
Ty : typeOf [] T1 intTy
Ty1 : typeOf [] T2 intTy
============================
typeOf [] (plus T1 T21) intTy
< apply IH to Ty1 Ev1.
Subgoal 5:
Variables: T21 T1 T2
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ev : value T1
Ev1 : eval T2 T21 *
Ty : typeOf [] T1 intTy
Ty1 : typeOf [] T2 intTy
H1 : typeOf [] T21 intTy
============================
typeOf [] (plus T1 T21) intTy
< search.
Subgoal 6:
Variables: Ty I I2 I1
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ty : typeOf [] (plus (num I1) (num I2)) Ty
Ev : I1 + I2 = I
============================
typeOf [] (num I) Ty
< Ty: case Ty.
Subgoal 6:
Variables: I I2 I1
IH : forall T Ty T', typeOf [] T Ty -> eval T T' * -> typeOf [] T' Ty
Ev : I1 + I2 = I
Ty : typeOf [] (num I1) intTy
Ty1 : typeOf [] (num I2) intTy
============================
typeOf [] (num I) intTy
< search.
Proof completed.
< Theorem subst_total :
forall X R T, host_is_tm T -> is_string X -> exists S, subst X R T S.
============================
forall X R T, host_is_tm T -> is_string X -> exists S, subst X R T S
< induction on 1.
IH : forall X R T, host_is_tm T * -> is_string X -> exists S, subst X R T S
============================
forall X R T, host_is_tm T @ -> is_string X -> exists S, subst X R T S
< intros IsT IsX.
Variables: X R T
IH : forall X R T, host_is_tm T * -> is_string X -> exists S, subst X R T S
IsT : host_is_tm T @
IsX : is_string X
============================
exists S, subst X R T S
< IsT: case IsT.
Subgoal 1:
Variables: X R X1
IH : forall X R T, host_is_tm T * -> is_string X -> exists S, subst X R T S
IsX : is_string X
IsT : is_string X1
============================
exists S, subst X R (var X1) S
< Or: apply is_string_eq_or_not to IsX IsT.
Subgoal 1:
Variables: X R X1
IH : forall X R T, host_is_tm T * -> is_string X -> exists S, subst X R T S
IsX : is_string X
IsT : is_string X1
Or : X = X1 \/ (X = X1 -> false)
============================
exists S, subst X R (var X1) S
< E: case Or.
Subgoal 1.1:
Variables: R X1
IH : forall X R T, host_is_tm T * -> is_string X -> exists S, subst X R T S
IsX : is_string X1
IsT : is_string X1
============================
exists S, subst X1 R (var X1) S
< search.
Subgoal 1.2:
Variables: X R X1
IH : forall X R T, host_is_tm T * -> is_string X -> exists S, subst X R T S
IsX : is_string X
IsT : is_string X1
E : X = X1 -> false
============================
exists S, subst X R (var X1) S
< search.
Subgoal 2:
Variables: X R B Ty X1
IH : forall X R T, host_is_tm T * -> is_string X -> exists S, subst X R T S
IsX : is_string X
IsT : is_string X1
IsT1 : host_is_ty Ty
IsT2 : host_is_tm B *
============================
exists S, subst X R (abs X1 Ty B) S
< Or: apply is_string_eq_or_not to IsX IsT.
Subgoal 2:
Variables: X R B Ty X1
IH : forall X R T, host_is_tm T * -> is_string X -> exists S, subst X R T S
IsX : is_string X
IsT : is_string X1
IsT1 : host_is_ty Ty
IsT2 : host_is_tm B *
Or : X = X1 \/ (X = X1 -> false)
============================
exists S, subst X R (abs X1 Ty B) S
< E: case Or.
Subgoal 2.1:
Variables: R B Ty X1
IH : forall X R T, host_is_tm T * -> is_string X -> exists S, subst X R T S
IsX : is_string X1
IsT : is_string X1
IsT1 : host_is_ty Ty
IsT2 : host_is_tm B *
============================
exists S, subst X1 R (abs X1 Ty B) S
< search.
Subgoal 2.2:
Variables: X R B Ty X1
IH : forall X R T, host_is_tm T * -> is_string X -> exists S, subst X R T S
IsX : is_string X
IsT : is_string X1
IsT1 : host_is_ty Ty
IsT2 : host_is_tm B *
E : X = X1 -> false
============================
exists S, subst X R (abs X1 Ty B) S
< apply IH to IsT2 IsX with
R = R.
Subgoal 2.2:
Variables: X R B Ty X1 S
IH : forall X R T, host_is_tm T * -> is_string X -> exists S, subst X R T S
IsX : is_string X
IsT : is_string X1
IsT1 : host_is_ty Ty
IsT2 : host_is_tm B *
E : X = X1 -> false
H1 : subst X R B S
============================
exists S, subst X R (abs X1 Ty B) S
< search.
Subgoal 3:
Variables: X R B A
IH : forall X R T, host_is_tm T * -> is_string X -> exists S, subst X R T S
IsX : is_string X
IsT : host_is_tm A *
IsT1 : host_is_tm B *
============================
exists S, subst X R (app A B) S
< apply IH to IsT IsX with
R = R.
Subgoal 3:
Variables: X R B A S
IH : forall X R T, host_is_tm T * -> is_string X -> exists S, subst X R T S
IsX : is_string X
IsT : host_is_tm A *
IsT1 : host_is_tm B *
H1 : subst X R A S
============================
exists S, subst X R (app A B) S
< apply IH to IsT1 IsX with
R = R.
Subgoal 3:
Variables: X R B A S S1
IH : forall X R T, host_is_tm T * -> is_string X -> exists S, subst X R T S
IsX : is_string X
IsT : host_is_tm A *
IsT1 : host_is_tm B *
H1 : subst X R A S
H2 : subst X R B S1
============================
exists S, subst X R (app A B) S
< search.
Subgoal 4:
Variables: X R I
IH : forall X R T, host_is_tm T * -> is_string X -> exists S, subst X R T S
IsX : is_string X
IsT : is_integer I
============================
exists S, subst X R (num I) S
< search.
Subgoal 5:
Variables: X R B A
IH : forall X R T, host_is_tm T * -> is_string X -> exists S, subst X R T S
IsX : is_string X
IsT : host_is_tm A *
IsT1 : host_is_tm B *
============================
exists S, subst X R (plus A B) S
< apply IH to IsT IsX with
R = R.
Subgoal 5:
Variables: X R B A S
IH : forall X R T, host_is_tm T * -> is_string X -> exists S, subst X R T S
IsX : is_string X
IsT : host_is_tm A *
IsT1 : host_is_tm B *
H1 : subst X R A S
============================
exists S, subst X R (plus A B) S
< apply IH to IsT1 IsX with
R = R.
Subgoal 5:
Variables: X R B A S S1
IH : forall X R T, host_is_tm T * -> is_string X -> exists S, subst X R T S
IsX : is_string X
IsT : host_is_tm A *
IsT1 : host_is_tm B *
H1 : subst X R A S
H2 : subst X R B S1
============================
exists S, subst X R (plus A B) S
< search.
Proof completed.
< Theorem canonical_form_intTy :
forall V, value V -> typeOf [] V intTy -> exists I, V = num I.
============================
forall V, value V -> typeOf [] V intTy -> exists I, V = num I
< intros V Ty.
Variables: V
V : value V
Ty : typeOf [] V intTy
============================
exists I, V = num I
< case V.
Subgoal 1:
Variables: T Ty X
Ty : typeOf [] (abs X Ty T) intTy
============================
exists I, abs X Ty T = num I
< case Ty.
Subgoal 2:
Variables: I
Ty : typeOf [] (num I) intTy
============================
exists I1, num I = num I1
< search.
Proof completed.
< Theorem canonical_form_arrowTy :
forall V Ty1 Ty2,
value V -> typeOf [] V (arrowTy Ty1 Ty2) -> exists X B, V = abs X Ty1 B.
============================
forall V Ty1 Ty2,
value V -> typeOf [] V (arrowTy Ty1 Ty2) -> exists X B, V = abs X Ty1 B
< intros V Ty.
Variables: V Ty1 Ty2
V : value V
Ty : typeOf [] V (arrowTy Ty1 Ty2)
============================
exists X B, V = abs X Ty1 B
< case V.
Subgoal 1:
Variables: Ty1 Ty2 T Ty X
Ty : typeOf [] (abs X Ty T) (arrowTy Ty1 Ty2)
============================
exists X1 B, abs X Ty T = abs X1 Ty1 B
< case Ty.
Subgoal 1:
Variables: Ty1 Ty2 T X
H1 : typeOf [(X, Ty1)] T Ty2
============================
exists X1 B, abs X Ty1 T = abs X1 Ty1 B
< search.
Subgoal 2:
Variables: Ty1 Ty2 I
Ty : typeOf [] (num I) (arrowTy Ty1 Ty2)
============================
exists X B, num I = abs X Ty1 B
< case Ty.
Proof completed.
< Theorem progress :
forall T Ty,
host_is_tm T -> typeOf [] T Ty -> (exists T', eval T T') \/ value T.
============================
forall T Ty,
host_is_tm T -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
< induction on 1.
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
============================
forall T Ty,
host_is_tm T @ -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
< intros IsT Ty.
Variables: T Ty
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT : host_is_tm T @
Ty : typeOf [] T Ty
============================
(exists T', eval T T') \/ value T
< IsT: case IsT.
Subgoal 1:
Variables: Ty X
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
Ty : typeOf [] (var X) Ty
IsT : is_string X
============================
(exists T', eval (var X) T') \/ value (var X)
< Ty: case Ty.
Subgoal 1:
Variables: Ty X
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT : is_string X
Ty : lookup [] X Ty
============================
(exists T', eval (var X) T') \/ value (var X)
< case Ty.
Subgoal 2:
Variables: Ty B Ty1 X
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
Ty : typeOf [] (abs X Ty1 B) Ty
IsT : is_string X
IsT1 : host_is_ty Ty1
IsT2 : host_is_tm B *
============================
(exists T', eval (abs X Ty1 B) T') \/ value (abs X Ty1 B)
< search.
Subgoal 3:
Variables: Ty B A
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
Ty : typeOf [] (app A B) Ty
IsT : host_is_tm A *
IsT1 : host_is_tm B *
============================
(exists T', eval (app A B) T') \/ value (app A B)
< Ty: case Ty.
Subgoal 3:
Variables: Ty B A Ty1
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT : host_is_tm A *
IsT1 : host_is_tm B *
Ty : typeOf [] A (arrowTy Ty1 Ty)
Ty1 : typeOf [] B Ty1
============================
(exists T', eval (app A B) T') \/ value (app A B)
< Or1: apply IH to IsT Ty.
Subgoal 3:
Variables: Ty B A Ty1
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT : host_is_tm A *
IsT1 : host_is_tm B *
Ty : typeOf [] A (arrowTy Ty1 Ty)
Ty1 : typeOf [] B Ty1
Or1 : (exists T', eval A T') \/ value A
============================
(exists T', eval (app A B) T') \/ value (app A B)
< Or2: apply IH to IsT1 Ty1.
Subgoal 3:
Variables: Ty B A Ty1
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT : host_is_tm A *
IsT1 : host_is_tm B *
Ty : typeOf [] A (arrowTy Ty1 Ty)
Ty1 : typeOf [] B Ty1
Or1 : (exists T', eval A T') \/ value A
Or2 : (exists T', eval B T') \/ value B
============================
(exists T', eval (app A B) T') \/ value (app A B)
< Ev1: case Or1.
Subgoal 3.1:
Variables: Ty B A Ty1 T'
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT : host_is_tm A *
IsT1 : host_is_tm B *
Ty : typeOf [] A (arrowTy Ty1 Ty)
Ty1 : typeOf [] B Ty1
Or2 : (exists T', eval B T') \/ value B
Ev1 : eval A T'
============================
(exists T', eval (app A B) T') \/ value (app A B)
< search.
Subgoal 3.2:
Variables: Ty B A Ty1
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT : host_is_tm A *
IsT1 : host_is_tm B *
Ty : typeOf [] A (arrowTy Ty1 Ty)
Ty1 : typeOf [] B Ty1
Or2 : (exists T', eval B T') \/ value B
Ev1 : value A
============================
(exists T', eval (app A B) T') \/ value (app A B)
< Ev2: case Or2.
Subgoal 3.2.1:
Variables: Ty B A Ty1 T'
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT : host_is_tm A *
IsT1 : host_is_tm B *
Ty : typeOf [] A (arrowTy Ty1 Ty)
Ty1 : typeOf [] B Ty1
Ev1 : value A
Ev2 : eval B T'
============================
(exists T', eval (app A B) T') \/ value (app A B)
< search.
Subgoal 3.2.2:
Variables: Ty B A Ty1
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT : host_is_tm A *
IsT1 : host_is_tm B *
Ty : typeOf [] A (arrowTy Ty1 Ty)
Ty1 : typeOf [] B Ty1
Ev1 : value A
Ev2 : value B
============================
(exists T', eval (app A B) T') \/ value (app A B)
< apply canonical_form_arrowTy to _ Ty.
Subgoal 3.2.2:
Variables: Ty B Ty1 X B1
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT : host_is_tm (abs X Ty1 B1) *
IsT1 : host_is_tm B *
Ty : typeOf [] (abs X Ty1 B1) (arrowTy Ty1 Ty)
Ty1 : typeOf [] B Ty1
Ev1 : value (abs X Ty1 B1)
Ev2 : value B
============================
(exists T', eval (app (abs X Ty1 B1) B) T') \/ value (app (abs X Ty1 B1) B)
< IsAbs: case IsT.
Subgoal 3.2.2:
Variables: Ty B Ty1 X B1
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT1 : host_is_tm B *
Ty : typeOf [] (abs X Ty1 B1) (arrowTy Ty1 Ty)
Ty1 : typeOf [] B Ty1
Ev1 : value (abs X Ty1 B1)
Ev2 : value B
IsAbs : is_string X
IsAbs1 : host_is_ty Ty1
IsAbs2 : host_is_tm B1 *
============================
(exists T', eval (app (abs X Ty1 B1) B) T') \/ value (app (abs X Ty1 B1) B)
< apply subst_total to IsAbs2 IsAbs with
R = B.
Subgoal 3.2.2:
Variables: Ty B Ty1 X B1 S
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT1 : host_is_tm B *
Ty : typeOf [] (abs X Ty1 B1) (arrowTy Ty1 Ty)
Ty1 : typeOf [] B Ty1
Ev1 : value (abs X Ty1 B1)
Ev2 : value B
IsAbs : is_string X
IsAbs1 : host_is_ty Ty1
IsAbs2 : host_is_tm B1 *
H1 : subst X B B1 S
============================
(exists T', eval (app (abs X Ty1 B1) B) T') \/ value (app (abs X Ty1 B1) B)
< search.
Subgoal 4:
Variables: Ty I
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
Ty : typeOf [] (num I) Ty
IsT : is_integer I
============================
(exists T', eval (num I) T') \/ value (num I)
< search.
Subgoal 5:
Variables: Ty B A
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
Ty : typeOf [] (plus A B) Ty
IsT : host_is_tm A *
IsT1 : host_is_tm B *
============================
(exists T', eval (plus A B) T') \/ value (plus A B)
< Ty: case Ty.
Subgoal 5:
Variables: B A
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT : host_is_tm A *
IsT1 : host_is_tm B *
Ty : typeOf [] A intTy
Ty1 : typeOf [] B intTy
============================
(exists T', eval (plus A B) T') \/ value (plus A B)
< Or1: apply IH to IsT Ty.
Subgoal 5:
Variables: B A
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT : host_is_tm A *
IsT1 : host_is_tm B *
Ty : typeOf [] A intTy
Ty1 : typeOf [] B intTy
Or1 : (exists T', eval A T') \/ value A
============================
(exists T', eval (plus A B) T') \/ value (plus A B)
< Or2: apply IH to IsT1 Ty1.
Subgoal 5:
Variables: B A
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT : host_is_tm A *
IsT1 : host_is_tm B *
Ty : typeOf [] A intTy
Ty1 : typeOf [] B intTy
Or1 : (exists T', eval A T') \/ value A
Or2 : (exists T', eval B T') \/ value B
============================
(exists T', eval (plus A B) T') \/ value (plus A B)
< Ev1: case Or1.
Subgoal 5.1:
Variables: B A T'
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT : host_is_tm A *
IsT1 : host_is_tm B *
Ty : typeOf [] A intTy
Ty1 : typeOf [] B intTy
Or2 : (exists T', eval B T') \/ value B
Ev1 : eval A T'
============================
(exists T', eval (plus A B) T') \/ value (plus A B)
< search.
Subgoal 5.2:
Variables: B A
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT : host_is_tm A *
IsT1 : host_is_tm B *
Ty : typeOf [] A intTy
Ty1 : typeOf [] B intTy
Or2 : (exists T', eval B T') \/ value B
Ev1 : value A
============================
(exists T', eval (plus A B) T') \/ value (plus A B)
< Ev2: case Or2.
Subgoal 5.2.1:
Variables: B A T'
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT : host_is_tm A *
IsT1 : host_is_tm B *
Ty : typeOf [] A intTy
Ty1 : typeOf [] B intTy
Ev1 : value A
Ev2 : eval B T'
============================
(exists T', eval (plus A B) T') \/ value (plus A B)
< search.
Subgoal 5.2.2:
Variables: B A
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT : host_is_tm A *
IsT1 : host_is_tm B *
Ty : typeOf [] A intTy
Ty1 : typeOf [] B intTy
Ev1 : value A
Ev2 : value B
============================
(exists T', eval (plus A B) T') \/ value (plus A B)
< apply canonical_form_intTy to _ Ty.
Subgoal 5.2.2:
Variables: B I
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT : host_is_tm (num I) *
IsT1 : host_is_tm B *
Ty : typeOf [] (num I) intTy
Ty1 : typeOf [] B intTy
Ev1 : value (num I)
Ev2 : value B
============================
(exists T', eval (plus (num I) B) T') \/ value (plus (num I) B)
< Is1: case IsT.
Subgoal 5.2.2:
Variables: B I
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT1 : host_is_tm B *
Ty : typeOf [] (num I) intTy
Ty1 : typeOf [] B intTy
Ev1 : value (num I)
Ev2 : value B
Is1 : is_integer I
============================
(exists T', eval (plus (num I) B) T') \/ value (plus (num I) B)
< apply canonical_form_intTy to _ Ty1.
Subgoal 5.2.2:
Variables: I I1
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
IsT1 : host_is_tm (num I1) *
Ty : typeOf [] (num I) intTy
Ty1 : typeOf [] (num I1) intTy
Ev1 : value (num I)
Ev2 : value (num I1)
Is1 : is_integer I
============================
(exists T', eval (plus (num I) (num I1)) T') \/ value (plus (num I) (num I1))
< Is2: case IsT1.
Subgoal 5.2.2:
Variables: I I1
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
Ty : typeOf [] (num I) intTy
Ty1 : typeOf [] (num I1) intTy
Ev1 : value (num I)
Ev2 : value (num I1)
Is1 : is_integer I
Is2 : is_integer I1
============================
(exists T', eval (plus (num I) (num I1)) T') \/ value (plus (num I) (num I1))
< apply plus_integer_total to Is1 Is2.
Subgoal 5.2.2:
Variables: I I1 N3
IH : forall T Ty,
host_is_tm T * -> typeOf [] T Ty -> (exists T', eval T T') \/ value T
Ty : typeOf [] (num I) intTy
Ty1 : typeOf [] (num I1) intTy
Ev1 : value (num I)
Ev2 : value (num I1)
Is1 : is_integer I
Is2 : is_integer I1
H1 : I + I1 = N3
============================
(exists T', eval (plus (num I) (num I1)) T') \/ value (plus (num I) (num I1))
< search.
Proof completed.