From Undecidability.TM Require Import Util.TM_facts Switch.
Section If.
Variable n : nat.
Variable sig : finType.
Variable pM1 : pTM sig bool n.
Variable F : finType.
Variable pM2 : pTM sig F n.
Variable pM3 : pTM sig F n.
Definition If := Switch pM1 (fun b => if b then pM2 else pM3).
Lemma If_Realise R1 R2 R3 :
pM1 ⊨ R1 ->
pM2 ⊨ R2 ->
pM3 ⊨ R3 ->
If ⊨ (R1 |_true) ∘ R2 ∪ (R1 |_false) ∘ R3.
Proof.
intros.
eapply Realise_monotone.
- eapply (Switch_Realise (R1 := R1) (R2 := (fun b => if b then R2 else R3))); eauto.
now intros [].
- hnf. intros H2 (f& t). intros ([ | ]& (y & H3&H3')). left. hnf. eauto. right. hnf. eauto.
Qed.
Lemma If_TerminatesIn R1 T1 T2 T3 :
pM1 ⊨ R1 ->
projT1 pM1 ↓ T1 ->
projT1 pM2 ↓ T2 ->
projT1 pM3 ↓ T3 ->
projT1 If ↓ (fun tin i => exists i1 i2, T1 tin i1 /\ 1 + i1 + i2 <= i /\
forall tout (b:bool),
R1 tin (b, tout) ->
if b then T2 tout i2
else T3 tout i2).
Proof.
intros HRelalise HTerm1 HTerm2 HTerm3.
eapply TerminatesIn_monotone.
- eapply Switch_TerminatesIn; cbn; eauto. instantiate (1 := fun f => if f then T2 else T3). intros [ | ]; cbn; auto.
- intros tin k (i1&i2&Hi&HT1&HT2). exists i1, i2. repeat split; eauto.
intros tout b HRel. specialize (HT2 tout b HRel). destruct b; auto.
Qed.
Lemma If_TerminatesIn' R1 T1 T2 T3 :
pM1 ⊨ R1 ->
projT1 pM1 ↓ T1 ->
projT1 pM2 ↓ T2 ->
projT1 pM3 ↓ T3 ->
projT1 If ↓ (fun tin i => exists i1, T1 tin i1 /\
forall tout (b:bool),
R1 tin (b, tout) ->
if b then exists i2, 1 + i1 + i2 <= i /\ T2 tout i2
else exists i3, 1 + i1 + i3 <= i /\ T3 tout i3).
Proof.
intros HRelalise HTerm1 HTerm2 HTerm3.
eapply TerminatesIn_monotone.
- eapply Switch_TerminatesIn'; cbn; eauto. instantiate (1 := fun f => if f then T2 else T3). intros [ | ]; cbn; auto.
- intros tin k (i1&HT1&H). exists i1. split.
+ assumption.
+ intros tout yout HR1. specialize H with (1 := HR1). destruct yout.
* destruct H as (i2&H&H'). eauto.
* destruct H as (i3&H&H'). eauto.
Qed.
Lemma If_RealiseIn R1 R2 R3 k1 k2 k3 :
pM1 ⊨c(k1) R1 ->
pM2 ⊨c(k2) R2 ->
pM3 ⊨c(k3) R3 ->
If ⊨c(1 + k1 + Nat.max k2 k3)
(R1 |_true) ∘ R2 ∪ (R1 |_false) ∘ R3.
Proof.
intros.
eapply RealiseIn_monotone.
eapply Switch_RealiseIn; eauto.
- intros. cbn in f. destruct f.
+ eapply RealiseIn_monotone. destruct pM2. eassumption. instantiate (1 := Nat.max k2 k3); firstorder.
lia. instantiate (1 := fun t => match t with true => R2 | _ => R3 end). reflexivity.
+ eapply RealiseIn_monotone. destruct pM3. eassumption. firstorder. lia. reflexivity.
- lia.
- hnf. intros H2 (f& t). intros ([ | ]& (y & H3&H3')). left. hnf. eauto. right. hnf. eauto.
Qed.
End If.
Arguments If : simpl never.
Section If.
Variable n : nat.
Variable sig : finType.
Variable pM1 : pTM sig bool n.
Variable F : finType.
Variable pM2 : pTM sig F n.
Variable pM3 : pTM sig F n.
Definition If := Switch pM1 (fun b => if b then pM2 else pM3).
Lemma If_Realise R1 R2 R3 :
pM1 ⊨ R1 ->
pM2 ⊨ R2 ->
pM3 ⊨ R3 ->
If ⊨ (R1 |_true) ∘ R2 ∪ (R1 |_false) ∘ R3.
Proof.
intros.
eapply Realise_monotone.
- eapply (Switch_Realise (R1 := R1) (R2 := (fun b => if b then R2 else R3))); eauto.
now intros [].
- hnf. intros H2 (f& t). intros ([ | ]& (y & H3&H3')). left. hnf. eauto. right. hnf. eauto.
Qed.
Lemma If_TerminatesIn R1 T1 T2 T3 :
pM1 ⊨ R1 ->
projT1 pM1 ↓ T1 ->
projT1 pM2 ↓ T2 ->
projT1 pM3 ↓ T3 ->
projT1 If ↓ (fun tin i => exists i1 i2, T1 tin i1 /\ 1 + i1 + i2 <= i /\
forall tout (b:bool),
R1 tin (b, tout) ->
if b then T2 tout i2
else T3 tout i2).
Proof.
intros HRelalise HTerm1 HTerm2 HTerm3.
eapply TerminatesIn_monotone.
- eapply Switch_TerminatesIn; cbn; eauto. instantiate (1 := fun f => if f then T2 else T3). intros [ | ]; cbn; auto.
- intros tin k (i1&i2&Hi&HT1&HT2). exists i1, i2. repeat split; eauto.
intros tout b HRel. specialize (HT2 tout b HRel). destruct b; auto.
Qed.
Lemma If_TerminatesIn' R1 T1 T2 T3 :
pM1 ⊨ R1 ->
projT1 pM1 ↓ T1 ->
projT1 pM2 ↓ T2 ->
projT1 pM3 ↓ T3 ->
projT1 If ↓ (fun tin i => exists i1, T1 tin i1 /\
forall tout (b:bool),
R1 tin (b, tout) ->
if b then exists i2, 1 + i1 + i2 <= i /\ T2 tout i2
else exists i3, 1 + i1 + i3 <= i /\ T3 tout i3).
Proof.
intros HRelalise HTerm1 HTerm2 HTerm3.
eapply TerminatesIn_monotone.
- eapply Switch_TerminatesIn'; cbn; eauto. instantiate (1 := fun f => if f then T2 else T3). intros [ | ]; cbn; auto.
- intros tin k (i1&HT1&H). exists i1. split.
+ assumption.
+ intros tout yout HR1. specialize H with (1 := HR1). destruct yout.
* destruct H as (i2&H&H'). eauto.
* destruct H as (i3&H&H'). eauto.
Qed.
Lemma If_RealiseIn R1 R2 R3 k1 k2 k3 :
pM1 ⊨c(k1) R1 ->
pM2 ⊨c(k2) R2 ->
pM3 ⊨c(k3) R3 ->
If ⊨c(1 + k1 + Nat.max k2 k3)
(R1 |_true) ∘ R2 ∪ (R1 |_false) ∘ R3.
Proof.
intros.
eapply RealiseIn_monotone.
eapply Switch_RealiseIn; eauto.
- intros. cbn in f. destruct f.
+ eapply RealiseIn_monotone. destruct pM2. eassumption. instantiate (1 := Nat.max k2 k3); firstorder.
lia. instantiate (1 := fun t => match t with true => R2 | _ => R3 end). reflexivity.
+ eapply RealiseIn_monotone. destruct pM3. eassumption. firstorder. lia. reflexivity.
- lia.
- hnf. intros H2 (f& t). intros ([ | ]& (y & H3&H3')). left. hnf. eauto. right. hnf. eauto.
Qed.
End If.
Arguments If : simpl never.