Theory CR.Critical_Pairs_Impl

(*
Author:  Christian Sternagel <c.sternagel@gmail.com> (2012-2015)
Author:  René Thiemann <rene.thiemann@uibk.ac.at> (2011-2015)
Author:  Thomas Sternagel <thomas.sternagel@uibk.ac.at> (2012)
License: LGPL (see file COPYING.LESSER)
*)
theory Critical_Pairs_Impl
imports 
  TRS.Critical_Pairs_Innermost
  Check_Joins
  TRS.Q_Restricted_Rewriting_Impl
  Show.Shows_Literal
begin

context fixes
  ren :: "'v :: infinite renaming2" 
begin
definition critical_pairs_impl :: "('f,'v)rules  ('f,'v)rules  (bool × ('f,'v)rule)list" 
  where "critical_pairs_impl P R  concat (map (λ (l,r). concat (map (λ p. let C = ctxt_of_pos_term p l; l'' = l |_ p; b = (C = ) in 
  if is_Var l'' then [] else concat (map (λ (l',r'). case mgu_vd ren l'' l' of Some (σ,τ)  [(b, (C c σ)r'  τ, r  σ)] | None  []) R)) (poss_list l))) P)"

lemma critical_pairs_impl[simp]: "set (critical_pairs_impl P R) = critical_pairs ren (set P) (set R)" (is "?l = ?r")
proof -
  note cpdefs = critical_pairs_impl_def critical_pairs_def set_concat
    set_map Let_def poss_list_sound
  {
    fix b s t
    assume "(b,s,t)  ?r"
    from this[unfolded cpdefs]
    obtain l r l' r' l'' C σ τ where
      b: "b = (C = )" and t: "t = r  σ" and s: "s = (C c σ)r'  τ"
      and P: "(l,r)  set P" and R: "(l', r')  set R"
      and l: "l = Cl''" and l'': "is_Fun l''"
      and mgu: "mgu_vd ren l'' l' = Some (σ, τ)"
      by auto
    let ?p = "hole_pos C"
    from l have p: "?p  poss l" by auto
    from l p have C: "C = ctxt_of_pos_term ?p l" by auto
    from l p have l: "l |_ ?p = l''" by auto
    have "(b,s,t)  ?l" unfolding cpdefs b s t
      by (rule, rule, rule P, unfold cpdefs, rule, rule imageI[OF p],
      insert C l R l'' mgu, force)
  } 
  then have "?r  ?l" by auto
  moreover
  {
    fix b s t
    assume "(b,s,t)  ?l"
    from this[unfolded cpdefs]
    obtain l r p l' r' σ τ where
      P: "(l,r)  set P" and p: "p  poss l" and lp: "is_Fun (l |_ p)" 
      and R: "(l',r')  set R" and mgu: "Some (σ,τ) = mgu_vd ren (l |_ p) l'" and b: "b = (ctxt_of_pos_term p l = )" and t: "t = r  σ" and s: "s = (ctxt_of_pos_term p l c σ)r'  τ"  by force
    have "(b,s,t)  ?r"
      by (rule critical_pairsI[OF P R _ lp mgu[symmetric] t s b], insert ctxt_supt_id[OF p], simp)
  }
  then have "?l  ?r" by auto
  ultimately show ?thesis by auto
qed

definition critical_pairs_top_impl :: "('f,'v)rules  ('f,'v)rules  (('f,'v)rule)list" 
  where "critical_pairs_top_impl P R  concat (map (λ (l,r).  
  if is_Var l then [] else concat (map (λ (l',r'). case mgu_vd ren l l' of Some (σ,τ)  [(r'  τ, r  σ)] | None  []) R)) P)"

lemma critical_pairs_top_impl[simp]: "set (critical_pairs_top_impl P R) = {(s,t). (True,s,t)  critical_pairs ren (set P) (set R)}" (is "?l = ?r")
proof -
  note cpdefs = critical_pairs_top_impl_def critical_pairs_def set_concat
    set_map
  {
    fix s t
    assume "(s,t)  ?r"
    from this[unfolded cpdefs]
    obtain l r l' r' l'' C σ τ where
      C: "C = " and t: "t = r  σ" and s: "s = (C c σ)r'  τ"
      and P: "(l,r)  set P" and R: "(l', r')  set R"
      and l: "l = Cl''" and l'': "is_Fun l''"
      and mgu: "mgu_vd ren l'' l' = Some (σ, τ)"
      by auto
    have "(s,t)  ?l" unfolding cpdefs s t 
      by (rule, rule, rule P, insert l[unfolded C] l'' mgu[symmetric] R C, force)
  }
  then have "?r  ?l" by auto
  moreover
  {
    fix s t
    assume st: "(s,t)  ?l"
    have id: " p b t e. p  set (if b then t else e) = (b  p  set t  ¬ b  p  set e)" by auto
    from st[unfolded cpdefs]
    obtain l r l' r' σ τ where
      P: "(l,r)  set P" and lp: "is_Fun l" 
      and R: "(l',r')  set R" and mgu: "Some (σ,τ) = mgu_vd ren l l'" and t: "t = r  σ" and s: "s = r'  τ" by (auto simp: id)
    have "(s,t)  ?r" unfolding s t
      by (rule, unfold split, rule critical_pairsI[OF P R _ lp mgu[symmetric] refl, of ], auto)
  }
  then have "?l  ?r" by auto
  ultimately show ?thesis by auto
qed
end

definition showsl_crit_pair :: "('f :: showl,'w :: showl)rule  showsl"
  where "showsl_crit_pair lr  
  showsl_lit (STR ''('')  showsl (fst lr)  showsl_lit (STR '', '')  
  showsl (snd lr)  showsl_lit (STR '')'')"

definition check_critical_pairs_cp_info :: "('f :: showl,'v :: showl)rules  (bool × ('f,'v)rule) list  ('f, 'v) cp_join_hints  showsl check"
  where "check_critical_pairs_cp_info R cp hints  do {
     checker  is_rsteps_join_one R hints;
     check_allm (λ (b,st). checker st) cp
  }"

definition check_critical_pairs_NF :: "('f :: showl,'v :: showl)rules  (bool × ('f,'v)rule) list  showsl check"
  where "check_critical_pairs_NF R cp  do {
    check_allm (λ (_,s,t). 
       if (s = t) then succeed else
       check_join_NF R s t
           <+? (λ e. showsl_lit (STR ''problem when joining critical pair '')  showsl_crit_pair (s,t)  showsl_nl  e)
    ) cp
  }"

datatype ('f,'v) join_info = Guided_BFS "('f,'v)cp_join_hints" | Join_NF

definition check_critical_pairs :: "('f :: showl,'v :: showl)rules  (bool × ('f,'v)rule) list  ('f,'v) join_info  showsl check"
  where "check_critical_pairs R cp join_info  case join_info of 
            Guided_BFS joins  check_critical_pairs_cp_info R cp joins 
          | Join_NF       check_critical_pairs_NF R cp"

context fixes
  ren :: "'v :: {infinite,showl} renaming2" 
begin

definition check_critical_pairs_innermost :: "('f :: showl,'v)rules  showsl check"
  where "check_critical_pairs_innermost R  
    check_allm (λ (l,r). check (l = r) (showsl_lit (STR ''there is a non-trivial critical pair '') 
       showsl_crit_pair (l,r))) (critical_pairs_top_impl ren R R)"

lemma check_critical_pairs_innermost: assumes ok: "isOK(check_critical_pairs_innermost R)" and NF: "NF_terms Q  NF_trs (set R)" 
  and var: " l r. (l,r)  set R  is_Fun l"
  shows "CR (qrstep nfs Q (set R))"
proof (rule critical_pairs_innermost[OF _ NF var])
  fix l r
  assume "(True,l,r)  critical_pairs ren (set R) (set R)"
  with ok[unfolded check_critical_pairs_innermost_def]
  show "l = r" by simp
qed

lemma check_critical_pairs_NF: fixes R :: "('f :: showl, 'v)rules"
  assumes ok: "isOK(check_critical_pairs_NF R (critical_pairs_impl ren R R))"
  shows "WCR (rstep (set R))"
proof (rule critical_pairs)
  fix t1 t2 b
  assume cp: "(b,t1,t2)  critical_pairs ren (set R) (set R)" and neq: "t1  t2"
  note ok = ok[unfolded check_critical_pairs_NF_def, unfolded Let_def, simplified]
  let ?Rel = "(rstep (set R))^*"
  from cp neq ok have "isOK(check_join_NF R t1 t2)"
    by auto
  from check_join_NF_sound[OF this] have "(t1,t2)  ?Rel O ?Rel^-1" by auto
  then obtain s where t1: "(t1,s)  ?Rel" and t2: "(t2,s)  ?Rel" by auto
  show " l' r' u. instance_rule (t1,t2) (l',r')  (l',u)  ?Rel  (r', u)  ?Rel"
  proof (intro exI conjI)
    show "instance_rule (t1,t2) (t1,t2)" by simp
  qed (insert t1 t2, auto)
qed    


lemma check_critical_pairs_NF_SN: fixes R :: "('f :: showl, 'v)rules"
  assumes SN: "SN (rstep (set R))"
  shows "isOK(check_critical_pairs_NF R (critical_pairs_impl ren R R)) = CR (rstep (set R))" (is "?check = ?CR")
proof (cases ?check)
  case True
  from check_critical_pairs_NF[OF True] have "WCR (rstep (set R))" .
  from Newman[OF SN this] True show ?thesis by simp
next
  case False
  let ?R = "rstep (set R)"
  from False[unfolded check_critical_pairs_NF_def]
  obtain b s t where bst: "(b,s,t)  critical_pairs ren (set R) (set R)" and ok: "¬ isOK (check_join_NF R s t)"
    by force
  from critical_pairs_fork[OF bst] obtain u where us: "(u,s)  ?R" and ut: "(u,t)  ?R" by blast+
  note get_NF = compute_rstep_NF_SN[OF SN]
  from get_NF[of s] obtain s' where s: "compute_rstep_NF R s = Some s'" ..
  from get_NF[of t] obtain t' where t: "compute_rstep_NF R t = Some t'" ..
  from ok[unfolded check_join_NF_def s t split option.simps] have neq: "s'  t'" by simp
  from us compute_rstep_NF_sound[OF s] have "(u,s')  ?R^*" by auto
  with compute_rstep_NF_complete[OF s] have us: "(u,s')  ?R^!" by auto
  from ut compute_rstep_NF_sound[OF t] have "(u,t')  ?R^*" by auto
  with compute_rstep_NF_complete[OF t] have ut: "(u,t')  ?R^!" by auto
  {
    assume ?CR
    from CR_imp_UNF[OF this] have "UNF ?R" .
    from UNF_onD[OF this _ us ut] neq have False by simp
  }
  with False show ?thesis by auto
qed

lemma check_critical_pairs_cp_info: 
  fixes R :: "('f :: showl, 'v)rules"
  and n :: nat
  assumes ok: "isOK(check_critical_pairs_cp_info R (critical_pairs_impl ren R R) infos)"
  shows "WCR (rstep (set R))"
proof (rule critical_pairs)
  fix t1 t2 b
  assume cp: "(b,t1,t2)  critical_pairs ren (set R) (set R)" and neq: "t1  t2"
  note ok = ok[unfolded check_critical_pairs_cp_info_def, simplified]
  from ok obtain checker where checker: "is_rsteps_join_one R infos = return checker" by auto
  note ok = ok[unfolded checker, simplified, rule_format, OF cp]
  let ?Rel = "(rstep (set R))^*"
  from ok have "isOK(checker (t1,t2))" by auto
  from is_rsteps_join_one[OF checker this] have "(t1,t2)  ?Rel O ?Rel^-1" by auto
  then obtain s where t1: "(t1,s)  ?Rel" and t2: "(t2,s)  ?Rel" by auto
  show " l' r' u. instance_rule (t1,t2) (l',r')  (l',u)  ?Rel  (r',u)  ?Rel"
  proof (intro exI conjI)
    show "instance_rule (t1,t2) (t1,t2)" by simp
  qed (insert t1 t2, auto)
qed


lemma check_critical_pairs: 
  fixes R :: "('f :: showl, 'v)rules"
  and n :: nat
  assumes ok: "isOK(check_critical_pairs R (critical_pairs_impl ren R R) joins_i)"
  shows "WCR (rstep (set R))"
proof -
  note ok = ok[unfolded check_critical_pairs_def]
  show ?thesis
  proof (cases joins_i)
    case (Guided_BFS joins)
    show ?thesis
      by (rule check_critical_pairs_cp_info, insert Guided_BFS ok, auto)
  next
    case Join_NF
    show ?thesis
      by (rule check_critical_pairs_NF, insert Join_NF ok, auto)
  qed
qed
    
end
end