Require Import LibEx.
Require Import bnat.
Require Import List.
Require Import ListEx.
Require Import Data.

Require Import Params.
Require Import Nand.
Require Import Dftl2.

Require Import Framework.
Require Import Inv.
Require Import FTLLemmas2.

Lemma bit_update_spec:forall bit pbn,valid_block_no pbn ->
                                 exists bi,bit_get bit pbn = Some bi.
Proof.
skip.
Qed.

Lemma invalid_old_page_spec:forall bit pbn off,exists bit',invalid_old_page bit pbn off = Some bit'.
Proof.
skip.
Qed.


(*
 * Copyright (C) BedRock Systems Inc. 2023
 *
 * This software is distributed under the terms of the BedRock Open-Source License.
 * See the LICENSE-BedRock file in the repository root for details.
 *)

Require Export bedrock.lang.cpp.bi.cfractional.

From bedrock.lang.bi Require Import prelude observe.
Require Import iris.proofmode.proofmode.

#[local] Set Primitive Projections.
#[local] Set Printing Coercions.
#[local] Set Default Proof Using "Type*".

(** * Spec building block: const/mutable fractional ownership *)
(**
Overview:

- [CFracSplittable_N R]

- Tactic [solve_cfrac] for solving [CFracSplittable_N]

[CFracSplittable_N R], where [N] counts the number of arguments taken
by [R] after its const/mutable fraction, is short-hand for:

- [R] is _timeless_, meaning it represents ownership;

- [R] is _const/mutable fractional_, meaning it can be split and
combined using [andb] on booleans and addition on fractions; and

- the fraction in [R] is _valid_, meaning [≤ 1].
*)

Ltac solve_cfrac := solve [intros; split; [apply _..|solve_cfrac_valid]].

Class CFracSplittable_0 {PROP : bi} (R : cQp.t → PROP) : Prop := {
  cfrac_splittable_0_fractional :> CFractional R;
  cfrac_splittable_0_timeless :> Timeless1 R;
  cfrac_splittable_0_frac_valid :> CFracValid0 R;
}.
Section cfrac_0.
  Context {PROP : bi} (R : cQp.t → PROP) `{!CFracSplittable_0 R}.

  #[global] Instance cfrac_splittable_0_as_fractional : AsCFractional0 R.
  Proof. solve_as_cfrac. Qed.
End cfrac_0.

Class CFracSplittable_1 {A} {PROP : bi} (R : cQp.t → A → PROP) : Prop := {
  cfrac_splittable_1_fractional :> CFractional1 R;
  cfrac_splittable_1_timeless :> Timeless2 R;
  cfrac_splittable_1_frac_valid :> CFracValid1 R;
}.
Section cfrac_1.
  Context {A} {PROP : bi} (R : cQp.t → A → PROP) `{!CFracSplittable_1 R}.

  #[global] Instance cfrac_splittable_1_as_fractional : AsCFractional1 R.
  Proof. solve_as_cfrac. Qed.
End cfrac_1.

Class CFracSplittable_2 {A B} {PROP : bi} (R : cQp.t → A → B → PROP) : Prop := {
  cfrac_splittable_2_fractional :> CFractional2 R;
  cfrac_splittable_2_timeless :> Timeless3 R;
  cfrac_splittable_2_frac_valid :> CFracValid2 R;
}.
Section cfrac_2.
  Context {A B} {PROP : bi} (R : cQp.t → A → B → PROP) `{!CFracSplittable_2 R}.

  #[global] Instance cfrac_splittable_2_as_fractional : AsCFractional2 R.
  Proof. solve_as_cfrac. Qed.
End cfrac_2.

Class CFracSplittable_3 {A B C} {PROP : bi}
    (R : cQp.t → A → B → C → PROP) : Prop := {
  cfrac_splittable_3_fractional :> CFractional3 R;
  cfrac_splittable_3_timeless :> Timeless4 R;
  cfrac_splittable_3_frac_valid :> CFracValid3 R;
}.
Section cfrac_3.
  Context {A B C} {PROP : bi} (R : cQp.t → A → B → C → PROP) `{!CFracSplittable_3 R}.

  #[global] Instance cfrac_splittable_3_as_fractional : AsCFractional3 R.
  Proof. solve_as_cfrac. Qed.
End cfrac_3.

Class CFracSplittable_4 {A B C D} {PROP : bi}
    (R : cQp.t → A → B → C → D → PROP) : Prop := {
  cfrac_splittable_4_fractional :> CFractional4 R;
  cfrac_splittable_4_timeless :> Timeless5 R;
  cfrac_splittable_4_frac_valid :> CFracValid4 R;
}.
Section cfrac_4.
  Context {A B C D} {PROP : bi} (R : cQp.t → A → B → C → D → PROP).
  Context `{!CFracSplittable_4 R}.

  #[global] Instance cfrac_splittable_4_as_fractional : AsCFractional4 R.
  Proof. solve_as_cfrac. Qed.
End cfrac_4.

Class CFracSplittable_5 {A B C D E} {PROP : bi}
    (R : cQp.t → A → B → C → D → E → PROP) : Prop := {
  cfrac_splittable_5_fractional :> CFractional5 R;
  cfrac_splittable_5_timeless :> Timeless6 R;
  cfrac_splittable_5_frac_valid :> CFracValid5 R;
}.
Section cfrac_5.
  Context {A B C D E} {PROP : bi} (R : cQp.t → A → B → C → D → E → PROP).
  Context `{!CFracSplittable_5 R}.

  #[global] Instance cfrac_splittable_5_as_fractional : AsCFractional5 R.
  Proof. solve_as_cfrac. Qed.
End cfrac_5.