Theory RS_Option

(***********************************************************************************
 * Copyright (c) 2025 Université Paris-Saclay
 *
 * Author: Benoît Ballenghien, Université Paris-Saclay,
           CNRS, ENS Paris-Saclay, LMF
 * Author: Benjamin Puyobro, Université Paris-Saclay,
           IRT SystemX, CNRS, ENS Paris-Saclay, LMF
 * Author: Burkhart Wolff, Université Paris-Saclay,
           CNRS, ENS Paris-Saclay, LMF
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * * Redistributions of source code must retain the above copyright notice, this
 *
 * * Redistributions in binary form must reproduce the above copyright notice,
 *   this list of conditions and the following disclaimer in the documentation
 *   and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * SPDX-License-Identifier: BSD-2-Clause
 ***********************************************************************************)


section ‹Option Type›

(*<*)
theory RS_Option
  imports Restriction_Spaces
begin
  (*>*)

subsection ‹Restriction option type›

instantiation option :: (restriction) restriction
begin

definition restriction_option :: ‹'a option ⇒ nat ⇒ 'a option›
  where ‹x ↓ n ≡ if n = 0 then None else map_option (λa. a ↓ n) x›

instance
  by intro_classes
    (simp add: restriction_option_def option.map_comp comp_def min_def)

end

lemma restriction_option_0_is_None [simp] : ‹x ↓ 0 = None›
  by (simp add: restriction_option_def)

lemma restriction_option_None [simp] : ‹None ↓ n = None›
  by (simp add: restriction_option_def)

lemma restriction_option_Some [simp] : ‹Some x ↓ n = (if n = 0 then None else Some (x ↓ n))›
  by (simp add: restriction_option_def)

lemma restriction_option_eq_None_iff : ‹x ↓ n = None ⟷ n = 0 ∨ x = None›
  by (cases x) simp_all

lemma restriction_option_eq_Some_iff : ‹x ↓ n = Some y ⟷ n ≠ 0 ∧ x ≠ None ∧ y = the x ↓ n›
  by (cases x) auto



subsection ‹Restriction space option type›

instance option :: (restriction_space) restriction_space
proof intro_classes
  show ‹x ↓ 0 = y ↓ 0› for x y :: ‹'a option› by simp
next
  show ‹x ≠ y ⟹ ∃n. x ↓ n ≠ y ↓ n› for x y :: ‹'a option›
    by (cases x; cases y, simp_all add: gt_ex)
      (metis bot_nat_0.not_eq_extremum ex_not_restriction_related restriction_0_related)
qed



subsection ‹Complete restriction space option type›

lemma option_restriction_chainE :
  fixes σ :: ‹nat ⇒ 'a :: restriction_space option› assumes ‹chain↓ σ›
  obtains ‹σ = (λn. None)›
  | σ' where ‹chain↓ σ'› and ‹σ = (λn. if n = 0 then None else Some (σ' n))›
proof -
  from ‹chain↓ σ› consider ‹∀n. σ n = None› | ‹∀n>0. σ n ≠ None›
    by (metis bot_nat_0.not_eq_extremum linorder_neqE_nat
        restriction_chain_def_bis restriction_option_eq_None_iff)
  thus thesis
  proof cases
    from that(1) show ‹∀n. σ n = None ⟹ thesis› by fast
  next
    define σ' where ‹σ' n ≡ if n = 0 then undefined ↓ 0 else the (σ n)› for n
    assume ‹∀n>0. σ n ≠ None›
    with ‹chain↓ σ› have ‹chain↓ σ'› ‹σ = (λn. if n = 0 then undefined ↓ 0 else Some (σ' n))›
      by (simp_all add: σ'_def restriction_chain_def)
        (metis option.sel restriction_option_eq_Some_iff,
          metis σ'_def bot_nat_0.not_eq_extremum option.sel restriction_option_0_is_None)
    with that(2) show thesis by force
  qed
qed


lemma non_destructive_Some : ‹non_destructive Some›
  by (simp add: non_destructiveI)

lemma restriction_cont_Some : ‹cont↓ (Some :: 'a :: restriction_space ⇒ 'a option)›
  by (rule restriction_shift_imp_restriction_cont[where k = 0])
    (simp add: restriction_shiftI)


instance option :: (complete_restriction_space) complete_restriction_space
proof intro_classes
  show ‹chain↓ σ ⟹ convergent↓ σ› for σ :: ‹nat ⇒ 'a option›
  proof (elim option_restriction_chainE)
    show ‹σ = (λn. None) ⟹ convergent↓ σ› by simp
  next
    fix σ' assume ‹chain↓ σ'› and σ_def : ‹σ = (λn. if n = 0 then None else Some (σ' n))›
    from ‹chain↓ σ'› have ‹convergent↓ σ'› by (simp add: restriction_chain_imp_restriction_convergent)
    hence ‹convergent↓ (λn. σ' (n + 1))› by (unfold restriction_convergent_shift_iff)
    then obtain Σ' where ‹(λn. σ' (n + 1)) ─↓→ Σ'› by (blast dest: restriction_convergentD')
    hence ‹(λn. Some (σ' (n + 1))) ─↓→ Some Σ'› by (fact restriction_contD[OF restriction_cont_Some])
    hence ‹convergent↓ (λn. Some (σ' (n + 1)))› by (blast intro: restriction_convergentI)
    hence ‹convergent↓ (λn. σ (n + 1))› by (simp add: σ_def)
    thus ‹convergent↓ σ› using restriction_convergent_shift_iff by blast
  qed
qed


(*<*)
end
  (*>*)