AUGER_LinearLogic - coq/coq GitHub Wiki

The content of a file for linear logic.

The use of a sequent "m, 1"

āˆ—
ā€¦
āŠ¢ ā€¦

is not natural and convenient at all for real proving; it is here only to illustrate how to use the Notation system, and what we can do with it.

(** Linear Logic in Coq *)
Require Import Utf8_core.
Require Import List.
Set Implicit Arguments.
Inductive linear_expression: Prop :=
| D: āˆ€ (is_positive: bool)
       (absolute_value: expression)
, linear_expression
with expression: Prop :=
| A: āˆ€ (atom: Prop)
, expression
| B: āˆ€ (left_expression: linear_expression)
       (is_multiplicative: bool)
       (right_expression: linear_expression)
, expression
| C: āˆ€ (is_multiplicative: bool)
, expression
| E: āˆ€ (delayed_expression: linear_expression)
, expression
.
Notation "a āŠ— b" := (D true (B a true b)) (at level 30).
Notation "a & b" := (D false (B a false b)) (at level 40).
Notation "a āŠ• b" := (D true (B a false b)) (at level 50).
Notation "a ā…‹ b" := (D false (B a true b)) (at level 60).
Notation "šŸ˜" := (D true (C false)).
Notation "šŸ™" := (D true (C true)).
Notation "āŠ„" := (D false (C true)).
Notation "āŠ¤" := (D false (C false)).
Notation "! a" := (D true (E a)) (at level 20).
Notation "? a" := (D false (E a)) (at level 20).
Notation "a āŗ" := (D true (A a)) (at level 10, format "a āŗ").
Notation "a ā»" := (D false (A a)) (at level 10, format "a ā»").
Example formula (A: Prop) := (?āŠ„āŠ•Aā»)āŠ—!(šŸ™&šŸ˜ā…‹āŠ¤).
Eval compute in (formula (0>1)).
Fixpoint linear_dual (e: linear_expression) :=
 match e with
 | D pos abs => D (if pos then false else true) (dual abs)
 end
 with dual e :=
 match e with
 | B l m r => B (linear_dual l) m (linear_dual r)
 | E l => E (linear_dual l)
 | _ => e
 end.
Notation "a ā½ā»ā¾" := (linear_dual a) (at level 10).
Eval compute in (Ī» (P: Prop), (formula P)ā½ā»ā¾).
Theorem linear_dual_idempotent: āˆ€ Ļ†, Ļ† = Ļ†ā½ā»ā¾ā½ā»ā¾
with dual_idempotent: āˆ€ Ļˆ, Ļˆ = dual (dual Ļˆ).
  Proof.
  intros [positivity absolute]; simpl.
  case dual_idempotent; case positivity; split.
 Proof.
 intros []; simpl; intros; repeat case linear_dual_idempotent; split.
Qed.
Fixpoint split i (lst: list linear_expression) :=
 match i with
 | O => (nil, lst)
 |S i=> match lst with
        |  nil  => (nil, nil)
        |le::lst=> let (l, r) := split i lst in (le::l, r)
        end
 end.
Inductive all_delayed: list linear_expression ā†’ Prop :=
| NoMoreDelays: all_delayed nil
| MoreDelays: āˆ€ l, all_delayed l ā†’ āˆ€ le, all_delayed (? le::l).
Inductive three_choices: Set := Birth | Life | Death.
Definition why_choice t le :=
 match t with
 | Birth => nil
 | Life => le::nil
 | Death => ? le::? le::nil
 end.
Inductive provable: list linear_expression ā†’ Prop :=
| Move: āˆ€ n l, provable (let (l, r) := split n l in r++l) ā†’ provable l
| Atom: āˆ€ P, provable (Pāŗ::Pā»::nil)
| Times: āˆ€ n lst a b, provable (a::(fst (split n lst))) ā†’
                      provable (b::(snd (split n lst))) ā†’
                      provable (aāŠ—b::lst)
| With: āˆ€ l a b, provable (a::l) ā†’ provable (b::l) ā†’ provable (a&b::l)
| Plus: āˆ€ l a b (c: bool),
        provable ((if c then a else b)::l) ā†’ provable (aāŠ•b::l)
| Par: āˆ€ l a b, provable (a::b::l) ā†’ provable (aā…‹b::l)
| One: provable (šŸ™::nil)
| Bottom: āˆ€ l, provable l ā†’ provable (āŠ„::l)
| Top: āˆ€ l, provable (āŠ¤::l)
| Bang: āˆ€ l, all_delayed l ā†’ āˆ€ le, provable (le::l) ā†’ provable (! le::l)
| Wnot: āˆ€ l t le, provable ((why_choice t le)++l) ā†’ provable (? le::l)
| Cut: āˆ€ t n lst, provable (t::(fst (split n lst))) ā†’
                  provable (linear_dual t::(snd (split n lst))) ā†’
                  provable lst.
Definition stack tl := List.map linear_dual tl.
Inductive these_provable hd tl : Prop :=
ProvableWrapper: provable (hd::(stack tl)) ā†’
                 these_provable hd tl.
Notation "āˆ— H1 .. H2 āŠ¢ J" :=
 (these_provable J (H1::..(H2::nil)..))
 (at level 100, format
  "'[v' āˆ— '/' H1 '/' .. '/' H2 '/' ']' āŠ¢ J"
 ).
Notation "āˆ— āŠ¢ J" :=
 (these_provable J nil)
 (at level 100, format
  "'[v' āˆ— '/' ']' āŠ¢ J"
 ).
Tactic Notation "linear" tactic(tac) :=
apply ProvableWrapper;
simpl;
tac;
simpl;
match goal with
| |- provable (?hd::?tl) =>
  cut (these_provable hd (stack tl)); simpl;
  [now intros []; simpl; clear;
   repeat case linear_dual_idempotent
  |repeat case linear_dual_idempotent]
end.
Ltac move_ n :=
apply Move with n.
Ltac times_ n :=
apply Times with n.
Ltac left_ :=
apply Plus with true.
Ltac right_ :=
apply Plus with false.
Ltac bang_ :=
apply Bang; [simpl; repeat constructor|].
Ltac weak_ :=
apply Wnot with Birth.
Ltac derel_ :=
apply Wnot with Life.
Ltac contr_ :=
apply Wnot with Death.
Ltac cut_ t n :=
apply Cut with t n.
Lemma linear_em: āˆ€ Ļ†, āˆ—Ļ†āŠ¢Ļ†
with lem: āˆ€ Ļˆ b, āˆ—D b Ļˆ āŠ¢ D b Ļˆ.
  Proof.
  clear -lem; intros [b Ļˆ].
  apply lem.
 Proof.
 clear lem; intros [a|Ļ†ā‚ Ī¼ Ļ†ā‚‚|[]|Ļ†];
 ((assert (Ī¦ā‚ := linear_em Ļ†ā‚); assert (Ī¦ā‚‚ := linear_em Ļ†ā‚‚))
||(assert (Ī¦ := linear_em Ļ†))
||idtac); (try case Ī¼); intros []; simpl; clear linear_em.
            now linear constructor.
           linear move_ 1.
           now linear constructor.
          linear move_ 1.
          linear constructor; move_ 2.
          now linear times_ 1.
         linear constructor; move_ 2.
         now linear times_ 1; move_ 1.
        linear move_ 1.
        linear constructor; move_ 1.
         now linear left_.
        now linear right_.
       linear constructor; move_ 1.
        now linear left_; move_ 1.
       now linear right_; move_ 1.
      linear move_ 1.
      now linear repeat constructor.
     now linear repeat constructor.
    linear move_ 1.
    now linear constructor.
   now linear constructor.
  linear bang_; move_ 1.
  now linear derel_; move_ 1.
 linear move_ 1.
 linear bang_; move_ 1.
 now linear derel_.
Qed.
Goal āˆ€ Ļ†, āˆ— āŠ¢Ļ†ā½ā»ā¾ā…‹Ļ†.
 intro Ļ†.
 linear constructor.
 apply linear_em.
Qed.