Theory Ordered_Resolution_Soundness

theory Ordered_Resolution_Soundness
  imports Grounded_Ordered_Resolution
begin

subsection ‹Soundness›

context grounded_ordered_resolution_calculus
begin

notation lifting.entails_𝒢 (infix "F" 50)

lemma factoring_sound:
  assumes factoring: "factoring D C"
  shows "{D} F {C}"
  using factoring
proof (cases D C rule: factoring.cases)
  case (factoringI D l1 μ 𝒱 t1 t2 l2 D' C)

  {
    fix I :: "'tG set" and γ :: 'subst

    assume
      entails_ground_instances: "DG  ground_instances 𝒱 D. I  DG" and
      C_is_ground: "clause.is_ground (C  γ)" and
      type_preserving_γ: "type_preserving_on (clause.vars C) 𝒱 γ" and
      𝒱: "infinite_variables_per_type 𝒱"

    obtain γ' where
      γ'_is_ground_subst: "term.is_ground_subst γ'" and
      type_preserving_γ': "type_preserving 𝒱 γ'" and
      γ'_γ: "x  clause.vars C. x ⋅v γ = x ⋅v γ'"
      using clause.type_preserving_ground_subst_extension[OF C_is_ground type_preserving_γ] .

    let ?DG = "clause.to_ground (D  μ  γ')"
    let ?DG' = "clause.to_ground (D'  μ  γ')"
    let ?lG1 = "literal.to_ground (l1 ⋅l μ ⋅l γ')"
    let ?lG2 = "literal.to_ground (l2 ⋅l μ ⋅l γ')"
    let ?tG1 = "term.to_ground (t1 ⋅t μ ⋅t γ')"
    let ?tG2 = "term.to_ground (t2 ⋅t μ ⋅t γ')"
    let ?CG = "clause.to_ground (C  γ')"

    have type_preserving_μ: "type_preserving_on (clause.vars D) 𝒱 μ"
      using factoringI(5)
      by blast

    have [simp]: "?tG2 = ?tG1"
      using factoringI(6) term.is_imgu_unifies_pair
      by metis

    have [simp]: "t1 ⋅t μ ⋅t γ' =  t1 ⋅t μ ⋅t γ"
      using γ'_γ term.subst_eq 
      unfolding factoringI
      by fastforce

    have "?DG  ground_instances 𝒱 D"
    proof(unfold ground_instances_def mem_Collect_eq fst_conv snd_conv,
          intro exI, intro conjI 𝒱)

      show "clause.to_ground (D  μ  γ') = clause.to_ground (D  μ  γ')"
        by simp
    next

      show "clause.is_ground (D  μ  γ')"
        using γ'_is_ground_subst clause.is_ground_subst_is_ground
        by auto
    next

      show "type_preserving_on (clause.vars D) 𝒱 (μ  γ')"
        using 
          type_preserving_μ
          type_preserving_γ'
          γ'_is_ground_subst
          term.type_preserving_ground_compose_ground_subst
        by presburger
    qed

    then have "I  ?DG"
      using entails_ground_instances
      by blast

    then have "I  clause.to_ground (C  γ)"
      using clause.subst_eq[OF γ'_γ[rule_format]]
      unfolding factoringI
      by auto
  }

  then show ?thesis
    unfolding
      factoringI(1, 2)
      ground.G_entails_def
      true_clss_def
      ground_instances_def
    by auto
qed

lemma resolution_sound:
  assumes resolution: "resolution D E C"
  shows "{E, D} F {C}"
  using resolution
proof (cases D E C rule: resolution.cases)
  case (resolutionI 𝒱1 𝒱2 ρ1 ρ2 E D 𝒱3 μ t1 t2 l1 l2 E' D' C)
  
  {
    fix I :: "'tG set" and γ :: 'subst

    assume
      E_entails_ground_instances: "EG  ground_instances 𝒱1 E. I  EG" and
      D_entails_ground_instances: "DG  ground_instances 𝒱2 D. I  DG" and
      C_is_ground: "clause.is_ground (C  γ)" and
      type_preserving_γ: "type_preserving_on (clause.vars C) 𝒱3 γ"

    obtain γ' where
      γ'_is_ground_subst: "term.is_ground_subst γ'" and
      type_preserving_γ': "type_preserving 𝒱3 γ'" and
      γ'_γ: "x  clause.vars C. x ⋅v γ = x ⋅v γ'"
      using clause.type_preserving_ground_subst_extension[OF C_is_ground type_preserving_γ] .

    let ?EG = "clause.to_ground (E  ρ1  μ  γ')"
    let ?DG = "clause.to_ground (D  ρ2  μ  γ')"

    let ?lG1 = "literal.to_ground (l1 ⋅l ρ1 ⋅l μ ⋅l γ')"
    let ?lG2 = "literal.to_ground (l2 ⋅l ρ2 ⋅l μ ⋅l γ')"

    let ?EG' = "clause.to_ground (E'  ρ1  μ  γ')"
    let ?DG' = "clause.to_ground (D'  ρ2  μ  γ')"

    let ?tG1 = "term.to_ground (t1 ⋅t ρ1 ⋅t μ ⋅t γ')"
    let ?tG2 = "term.to_ground (t2 ⋅t ρ2 ⋅t μ ⋅t γ')"

    let ?CG = "clause.to_ground (C  γ')"

    have μ_γ'_is_ground_subst: "term.is_ground_subst (μ  γ')"
      using term.is_ground_subst_comp_right[OF γ'_is_ground_subst] .

    have type_preserving_μ: "type_preserving_on (clause.vars (E  ρ1)  clause.vars (D  ρ2)) 𝒱3 μ"
      using resolutionI(9)
      by blast

    have type_preserving_μ_γ:
      "type_preserving_on (clause.vars (E  ρ1)  clause.vars (D  ρ2)) 𝒱3 (μ  γ')"
      using 
        type_preserving_γ'
        type_preserving_μ
        γ'_is_ground_subst 
        term.type_preserving_ground_compose_ground_subst 
      by presburger

    note type_preserving_ρ_μ_γ = term.renaming_ground_subst[OF _ μ_γ'_is_ground_subst]

    have "?EG  ground_instances 𝒱1 E"
      proof(
        unfold ground_instances_def mem_Collect_eq fst_conv snd_conv,
        intro exI, intro conjI resolutionI)

      show "clause.to_ground (E  ρ1  μ  γ') = clause.to_ground (E  ρ1  μ  γ')"
        by simp
    next

      show "clause.is_ground (E  ρ1  μ  γ')"
        using γ'_is_ground_subst clause.is_ground_subst_is_ground
        by auto
    next

      show "type_preserving_on (clause.vars E) 𝒱1 (ρ1  μ  γ')"
        using
          type_preserving_μ_γ
          type_preserving_ρ_μ_γ[OF resolutionI(6, 18) _ resolutionI(16)]
        by (simp add: term.assoc clause.vars_subst)
    qed

    then have entails_EG: "I  ?EG"
      using E_entails_ground_instances
      by blast

    have "?DG  ground_instances 𝒱2 D"
    proof(
        unfold ground_instances_def mem_Collect_eq fst_conv snd_conv,
        intro exI, intro conjI resolutionI)

      show "clause.to_ground (D  ρ2  μ  γ') = clause.to_ground (D  ρ2  μ  γ')"
        by simp
    next

      show "clause.is_ground (D  ρ2  μ  γ')"
        using γ'_is_ground_subst clause.is_ground_subst_is_ground
        by auto
    next

      show "type_preserving_on (clause.vars D) 𝒱2 (ρ2  μ  γ')"
        using
          type_preserving_μ_γ
          type_preserving_ρ_μ_γ[OF resolutionI(7, 19) _ resolutionI(17)]
        by (simp add: term.assoc clause.vars_subst)
    qed

    then have entails_DG: "I  ?DG"
      using D_entails_ground_instances
      by blast

    have "I  clause.to_ground (C  γ')"
    proof -
      have [simp]: "?tG1 = ?tG2"
        using resolutionI(10) term.is_imgu_unifies_pair
        by metis

      have [simp]: "?lG1 = Neg ?tG1"
        unfolding resolutionI
        by simp

      have [simp]: "?lG2 = Pos ?tG2"
        unfolding resolutionI
        by simp

      have [simp]: "?EG = add_mset ?lG1 ?EG'"
        unfolding resolutionI
        by simp

      have [simp]: "?DG = add_mset ?lG2 ?DG'"
        unfolding resolutionI
        by simp

      have "¬ I ⊫l ?lG1  ¬ I ⊫l ?lG2"
        by simp

      then have "I  ?EG'  I  ?DG'"
        using entails_EG entails_DG
        by force

      moreover have "?CG = ?EG' + ?DG'"
        unfolding resolutionI
        by simp

      ultimately show ?thesis
        by auto
    qed

    then have "I  clause.to_ground (C  γ)"
      by (metis γ'_γ clause.subst_eq)
  }

  then show ?thesis
    unfolding ground.G_entails_def ground_instances_def true_clss_def resolutionI(1-3)
    by auto   
qed

sublocale sound_inference_system inferences "F" "(⊫F)"
proof unfold_locales
fix ι

  assume "ι  inferences"

  then show "set (prems_of ι) F {concl_of ι}"
    using
      factoring_sound
      resolution_sound
    unfolding inferences_def ground.G_entails_def
    by auto
qed

end

sublocale ordered_resolution_calculus  sound_inference_system inferences "F" entails_𝒢
proof unfold_locales
  obtain selectG where selectG: "selectG  selectGs"
    using Q_nonempty by blast

  then interpret grounded_ordered_resolution_calculus
    where selectG = selectG
    by unfold_locales (simp add: selectGs_def)

  fix ι
  assume "ι  inferences"

  then show "entails_𝒢 (set (prems_of ι)) {concl_of ι}"
    unfolding entails_def
    using sound
    by blast
qed

end