From PslBase Require Import Base FinTypes.
From Undecidability.L.Complexity Require Import MorePrelim Problems.Cook.TPR Problems.Cook.PR.
Require Import Lia.
From Undecidability.L.Complexity Require Import MorePrelim Problems.Cook.TPR Problems.Cook.PR.
Require Import Lia.
*Reduction of 3-PR to PR.
Section fixInstance.
Variable (FSigma : Type).
Variable (Finit : list FSigma).
Variable (Fwindows : list (TPRWin FSigma)).
Variable (Ffinal : list (list FSigma)).
Variable (Fsteps : nat).
Definition TPRWin_to_PRWin (X : Type) (win : TPRWin X) := Build_PRWin (TPRWinP_to_list (TPR.prem win)) (TPRWinP_to_list (TPR.conc win)).
Definition PR_windows := map (@TPRWin_to_PRWin FSigma) Fwindows.
Hint Constructors PR.valid.
Hint Constructors TPR.valid.
Lemma valid_agree (s1 s2 : list FSigma) :
|s1| >= 3 -> TPR.valid (rewritesHeadList Fwindows) s1 s2 <-> PR.valid 1 3 PR_windows s1 s2.
Proof.
intros; split.
- induction 1.
+ eauto.
+ cbn in H; lia.
+ replace (x :: a) with ([x] ++ a) by now cbn. replace (y :: b) with ([y] ++ b) by now cbn.
destruct H1 as (win & H3 & H4).
destruct (le_lt_dec 3 (|a|)) as [H2 | H2].
* econstructor 3; [apply IHvalid; lia | easy | easy | apply in_map_iff | ].
-- exists win. split; [reflexivity | easy].
-- unfold rewritesHead. cbn. easy.
* assert (|a| = 2) as H1 by now cbn in H. clear H2 H IHvalid.
apply TPR.valid_length_inv in H0. rewrite H1 in H0.
list_length_inv. econstructor 3; [ eapply valid_vacuous with (m := 2); cbn; eauto | easy | easy | | ].
-- apply in_map_iff. exists win; split; [ reflexivity | easy].
-- destruct H4. cbn; split; eauto.
- induction 1.
+ eauto.
+ rewrite app_length in H; lia.
+ list_length_inv. cbn in *. unfold PR_windows in H3. apply in_map_iff in H3 as (win' & <- & H3).
destruct (le_lt_dec 3 (|a|)) as [H1 | H1].
* econstructor 3; [ apply IHvalid; lia | exists win'; split; [ apply H3 | ]].
destruct H4; split; eauto.
* assert (|a| = 2) by lia. clear IHvalid H1 H. apply valid_length_inv in H0. rewrite H2 in H0.
list_length_inv. constructor 3; [ apply TPR.valid_vacuous; cbn; eauto| ].
exists win'; split; [apply H3 | ]. destruct H4; split; eauto.
Qed.
Lemma relpower_valid_agree k (s1 s2 : list FSigma) :
|s1| >= 3 -> relpower (TPR.valid (rewritesHeadList Fwindows)) k s1 s2 <-> relpower (PR.valid 1 3 PR_windows) k s1 s2.
Proof.
intros; split; induction 1; [ eauto | | eauto | ].
- econstructor; [ apply valid_agree; [apply H | apply H0] | apply IHrelpower].
apply TPR.valid_length_inv in H0; lia.
- econstructor; [ apply valid_agree; [ apply H | apply H0] | apply IHrelpower].
apply valid_length_inv in H0; lia.
Qed.
Lemma final_agree (s : list FSigma) : |s| = |Finit| -> TPR.satFinal Ffinal s <-> PR.satFinal 1 (length Finit) Ffinal s.
Proof.
unfold TPR.satFinal, satFinal. setoid_rewrite Nat.mul_1_r. split; intros.
- destruct H0 as (subs & H1 & H2). exists subs.
destruct H2 as (b1 & b2 & ->).
exists (|b1|). split; [ apply H1 | ].
rewrite skipn_app; [ | easy].
split; [ rewrite !app_length in H; lia | now exists b2].
- destruct H0 as (subs & k & H1 & H2 & (b & H3)). exists subs. split; [ apply H1 | ].
unfold substring.
setoid_rewrite <- (firstn_skipn k s). setoid_rewrite H3.
exists (firstn k s), b. easy.
Qed.
End fixInstance.
Definition PR_instance (tpr : TPR) := Build_PR 1 3 (TPR.init tpr) (PR_windows (TPR.windows tpr)) (TPR.final tpr) (TPR.steps tpr).
Lemma TPR_to_PR (tpr : TPR) : TPRLang tpr <-> PRLang (PR_instance tpr).
Proof.
split; intros.
- destruct H as (H & sf & H1 & H2). split; [ | exists sf; repeat split].
+ repeat split; cbn in *; [ lia | lia | exists 3; split; lia | apply H | | | ].
* unfold PR_windows in *. apply in_map_iff in H0 as (win' & <- & H0). cbn. destruct win', prem, conc; now cbn.
* unfold PR_windows in *. apply in_map_iff in H0 as (win' & <- & H0). cbn. destruct win', prem, conc; now cbn.
* setoid_rewrite Nat.mul_1_r. eauto.
+ apply relpower_valid_agree, H1. apply H.
+ apply final_agree, H2. apply TPR.relpower_valid_length_inv in H1; cbn. lia.
- destruct H as (H1 & sf & H2 & H3). split; [ | exists sf; repeat split]; cbn in *.
+ destruct H1 as (_ & _ & _ & H1 &_). cbn in H1. apply H1.
+ apply relpower_valid_agree; [ apply H1 | apply H2].
+ eapply final_agree, H3. apply relpower_valid_length_inv in H2. lia.
Qed.