why3doc index index


(* Definitions of tools that allow reasoning on games without strategy:
   defines u-accessibility and victory invariants. *)
module StratLessDef

  use import game.Game
  use import ho_set.Set
  use import ho_set.SetBigOps
  use import order.LimUniq
  use import order.Chain
  use import transfinite.ExtensionDef

  (* u-accessibility of an history: can be reached by some demon. *)
  predicate u_acc (g:game 'a) (ang:angel 'a) (x:'a) (h:set 'a) =
    exists dmn. tr_ext g.progress (step g ang dmn) ((=) x) h

  predicate u_acc_s (g:game 'a) (ang:angel 'a) (start:set 'a) (h:set 'a) =
    exists x. start x /\ u_acc g ang x h

  (* Strong u-accessibility: can be extended through u_acc_step. *)
  predicate u_acc_step (g:game 'a) (ang:angel 'a) (h:set 'a) (n:'a) =
    let x = sup g.progress h in
    let a = ang h in
    supremum g.progress h x /\
    if h x then g.transition x a /\ a n /\ not a x else n = x

  predicate strong_u_acc (g:game 'a) (ang:angel 'a) (x:'a) (h:set 'a) =
    tr_ext g.progress (u_acc_step g ang) ((=) x) h

  predicate strong_u_acc_s (g:game 'a) (ang:angel 'a) (start h:set 'a) =
    exists u. start u /\ strong_u_acc g ang u h

  lemma u_acc_step_is_tr_succ : forall g:game 'a,ang.
    tr_succ g.progress (u_acc_step g ang)
    by let o = g.progress in
      forall h n. u_acc_step g ang h n -> upper_bound o h n
      by o (sup g.progress h) n

  (* The angel defininetely lose at some point iff:
     . it did not win
     . Either it makes an invalid choice, or allows a loop. *)
  predicate lose_at (g:game 'a) (ang:angel 'a) (win h:set 'a) =
    (forall u. h u -> not win u) /\
    exists x. maximum g.progress h x /\
      let a = ang h in not g.transition x a \/ a x

  (* Alternative proof objects for enforce: victory invariants. *)
  predicate next_hist (inv:set (set 'a)) (h:set 'a) (y:'a) =
    inv (add h y)
  predicate victory_invariant (g:game 'a) (p q:set 'a) (inv:set (set 'a)) =
    let o = g.progress in
    (forall x. p x -> inv ((=) x)) /\
    (forall h x. inv h /\ not inhabited (inter h q) /\ maximum o h x ->
      exists a. g.transition x a /\ not a x /\ subset a (next_hist inv h)) /\
    (forall ch. subset ch inv /\ chain (subchain o) ch /\ inhabited ch ->
      inv (bigunion ch)) /\
    (forall h x. inv h /\ supremum o h x -> inv (add h x))

  (* More precise link: victory invariant can prove strategy winning. *)
  predicate winning_cause (g:game 'a) (q:set 'a)
                          (inv:set (set 'a)) (ang:angel 'a) =
    forall h x. inv h /\ maximum g.progress h x /\ not inhabited (inter h q) ->
      let a = ang h in
      subset a (next_hist inv h) /\ g.transition x a /\ not a x

end

 (* Properties about u-accessibilities *)
module Uacc "W:non_conservative_extension:N" (* => UaccProof *)

  use import game.Game
  use export StratLessDef
  use import ho_set.Set
  use import ho_set.SetBigOps
  use import order.Chain
  use import transfinite.ExtensionDef

  (* Propagation rules. *)
  axiom u_acc_base : forall g ang,x:'a. u_acc g ang x ((=) x)

  axiom u_acc_next : forall g ang h,x0 x y:'a.
    u_acc g ang x0 h /\ maximum g.progress h x ->
    let a = ang h in g.transition x a /\ a y /\ not a x ->
    u_acc g ang x0 (add h y)

  axiom u_acc_lim : forall g ang ch,x0:'a.
    chain (subchain g.progress) ch /\ inhabited ch ->
    subset ch (u_acc g ang x0) -> u_acc g ang x0 (bigunion ch)

  axiom u_acc_sup : forall g ang h,x0 x:'a.
    supremum g.progress h x /\ u_acc g ang x0 h -> u_acc g ang x0 (add h x)

  (* In particular, contains the least fixpoint of propagation rules. *)
  axiom u_acc_by_step : forall g ang h,x0:'a.
    strong_u_acc g ang x0 h -> u_acc g ang x0 h

  (* Refinement on the next version that builds explicitly a demon
     in order to map the angel transition to the choice, also
     working in the case of loops. *)
  axiom u_acc_rebuild : forall g ang h,x0 x y:'a.
    u_acc g ang x0 h /\ maximum g.progress h x ->
    let a = ang h in g.transition x a /\ a y /\ (a x -> y = x) ->
    exists dmn. tr_ext g.progress (step g ang dmn) ((=) x0) h /\ dmn a = y

end

(* Alternative criterions for winning strategies (and win-strat existence) *)
module WinAlt "W:non_conservative_extension:N" (* => WinAltProof *)

  use import game.Game
  use export StratLessDef
  use import transfinite.ExtensionDef

  (* a strategy is winning iff there are no losing history
     among (strong) u-accessible. *)
  axiom u_acc_losing : forall g:game 'a,ang x0 win.
    winning_strat g x0 win ang <->
      forall h. u_acc g ang x0 h -> not lose_at g ang win h

  axiom strong_u_acc_losing : forall g:game 'a,ang x0 win.
    winning_strat g x0 win ang <->
      forall h. strong_u_acc g ang x0 h -> not lose_at g ang win h

  (* Victory invariant realise alternative proof objects. *)
  axiom victory_invariant_ok : forall g:game 'a,start win.
    (exists inv. victory_invariant g start win inv)
    <-> have_uniform_winning_strat g start win

  (* Derivation of winning strategies from victory invariant. *)
  axiom win_strat_from_victory_invariant : forall g:game 'a,ang inv start win.
    victory_invariant g start win inv /\ winning_cause g win inv ang ->
    uniform_winning_strat g start win ang

  (* Victory invariant from winning strategies:
     (strongly) u-accessibles. *)
  axiom victory_invariant_from_win_strat_1 : forall g:game 'a,ang start win.
    uniform_winning_strat g start win ang ->
    victory_invariant g start win (u_acc_s g ang start)

  axiom victory_invariant_from_win_strat_2 : forall g:game 'a,ang start win.
    uniform_winning_strat g start win ang ->
    victory_invariant g start win (strong_u_acc_s g ang start)

end

(* Basic manipulation on victory invariant. *)
module InvExtraDef

  use import game.Game
  use import order.Ordered
  use import ho_set.Set
  use import ho_rel.RelSet
  use import StratLessDef

  (* Cropping: enforce the absence of history past the winning set. *)
  predicate cropped (o:erel 'a) (win:set 'a) (inv:set (set 'a)) =
    forall h x. inv h /\ inter h win x -> maximum o h x
  function crop (o:erel 'a) (win:set 'a) (inv:set (set 'a)) : set (set 'a) =
    fun h -> inv h /\ forall x. inter h win x -> maximum o h x

  (* accessibility reduction: if we have a 'super-strategy'
     (which gives some supersets of transitions instead of regular
      transitions) for which a victory invariant is winning cause,
      then the (strongly) u-accessible history for that strategy
      that were accessible through the invariant form a smaller invariant.
      For the 'super-transitions' to be feasible, we need to take
      (strong) u-accessibility in a larger but equivalent game
      where those are feasible.
      Of course, the most useful case is strong u-accessibility,
      which add an inductive structure to the victory invariant.
   *)
  let ghost function span_game (g:game {'a}) : game {'a} =
    { progress = g.progress;
      transition = pure { fun x s -> related subset (g.transition x) s
        /\ lower_bound g.progress s x } }
  function crop_ang (inv:set (set 'a)) (ang:angel 'a) : angel 'a =
    fun h x -> inv (add h x) /\ ang h x

end

module InvExtra "W:non_conservative_extension:N" (* => InvExtraProof *)

  use import game.Game
  use import ho_set.Set
  use export InvExtraDef
  use export StratLessDef

  axiom cropping : forall g:game 'a,start win inv.
    victory_invariant g start win inv ->
    victory_invariant g start win (crop g.progress win inv)

  axiom cropping_access : forall g:game 'a,start win ang inv.
    victory_invariant g start win inv /\
    winning_cause (span_game g) win inv ang ->
    let ninv = strong_u_acc_s (span_game g) (crop_ang inv ang) start in
    subset ninv inv /\
    victory_invariant g start win ninv

end

module UaccProof

  use import game.Game
  use import StratLessDef
  use import ho_set.Set
  use import ho_set.SetBigOps
  use import order.LimUniq
  use import order.SubChain
  use import fn.Fun
  use import choice.Choice
  use import transfinite.ExtensionDet
  use import transfinite.Transport

  lemma u_acc_base : forall g ang,x:'a. u_acc g ang x ((=) x)
    by exists dmn. true so tr_ext g.progress (step g ang dmn) ((=) x) ((=) x)

  predicate dmn_witness (g:game 'a) (ang:angel 'a)
                        (x:'a) (h:set 'a) (dmn:demon 'a) =
    tr_ext g.progress (step g ang dmn) ((=) x) h

  predicate same_choices (g:game 'a) (ang:angel 'a) (h:set 'a)
                         (dmn1 dmn2:demon 'a) =
    forall h0 x. subchain g.progress h0 h /\ maximum g.progress h0 x /\
      h <> h0 -> dmn1 (ang h0) = dmn2 (ang h0)

  (* With fixed angel/start, two demons reach the same history iff
     they made the same choice before. Direct consequence of
     transport of transfinite extensions. *)
  lemma dmn_witness_criterion : forall g ang x0 h,dmn1 dmn2:demon 'a.
    dmn_witness g ang x0 h dmn1 ->
      (dmn_witness g ang x0 h dmn2 <-> same_choices g ang h dmn1 dmn2)
    by let o = g.progress in
      let st1 = step g ang dmn1 in
      let st2 = step g ang dmn2 in
      let ex = (=) x0 in
      (same_choices g ang h dmn1 dmn2 <->
        transport_criterion o st2 ex h)
    by transport_criterion o st1 ex h
    so (same_choices g ang h dmn1 dmn2 ->
      forall h0 x. subchain o ex h0 /\ subchain o (add h0 x) h /\
        upper_bound o h0 x /\ not h0 x -> st2 h0 x
      by st1 h0 x
      so let s = sup o h0 in
        let a = ang h0 in
        (h0 s -> dmn1 a = dmn2 a by maximum o h0 s /\ subchain o h0 h)
    ) /\ (transport_criterion o st2 ex h ->
      forall h0 x. subchain o h0 h /\ maximum o h0 x /\ h <> h0 ->
        let a = ang h0 in
        let y = dmn1 a in
        y = dmn2 a
        by (subchain o ex h0 || (false by sext h0 ex by subchain o h0 ex))
        so (st1 h0 y /\ not h0 y)
          || (false by maximum (subchain o) (tr_ext o st1 ex) h0)
        so st2 h0 y
        by not (not subchain o (add h0 y) h
                so subchain o h (add h0 y)
                so not sext h h0)
        so upper_bound o h0 y
    )

  lemma u_acc_rebuild : forall g ang h,x0 x y:'a.
    let o = g.progress in
    u_acc g ang x0 h /\ maximum o h x ->
    let a = ang h in g.transition x a /\ a y /\ (a x -> y = x) ->
    let ex = (=) x0 in
    exists dmn. let st = step g ang dmn in
      tr_ext o st ex h /\ dmn a = y
    by exists dmn0. let st0 = step g ang dmn0 in
      tr_ext o st0 ex h /\ dmn = update dmn0 a y
    so same_choices g ang h dmn dmn0
    by forall h0 x0. subchain o h0 h /\ maximum o h0 x0 /\ h <> h0 ->
      not (dmn (ang h0) <> dmn0 (ang h0)
           so ang h0 = a
           so subchain o ex h0 || (false by subchain o h0 ex so sext h0 none)
           so st0 h0 (dmn0 a)
             || (false by maximum (subchain o) (tr_ext o st0 ex) h0)
           so let h1 = add h0 (dmn0 a) in
             if subchain o h1 h
             then o x (dmn0 a) /\ o (dmn0 a) x
             else false by subchain o h h1 so not sext h h0
          )

  lemma u_acc_next : forall g ang h,x0 x y:'a.
    let o = g.progress in
    u_acc g ang x0 h /\ maximum o h x ->
    let a = ang h in g.transition x a /\ a y /\ not a x ->
    u_acc g ang x0 (add h y)
    by exists dmn. tr_ext o (step g ang dmn) ((=) x0) h /\ dmn a = y
    so tr_ext o (step g ang dmn) ((=) x0) (add h y)

  lemma u_acc_sup : forall g ang h,x0 x:'a.
    let o = g.progress in
    supremum o h x /\ u_acc g ang x0 h ->
    u_acc g ang x0 (add h x)
    by if h x then sext h (add h x) else true

  lemma u_acc_lim : forall g ang ch,x0:'a.
    let o = g.progress in let hl = bigunion ch in
    chain (subchain o) ch /\ inhabited ch ->
    subset ch (u_acc g ang x0) -> u_acc g ang x0 hl
    by supremum (subchain o) ch hl
      (* Choice of demons for each history in the chain *)
    so let dmn_h= fun h -> choice (dmn_witness g ang x0 h) in
      (forall h. ch h -> dmn_witness g ang x0 h (dmn_h h)
        by exists dmn. dmn_witness g ang x0 h dmn)
    so (* Choice of super-chain given any history. *)
      let p0 = fun h0 s -> subchain o h0 s /\ h0 <> s /\ ch s in
      let supr = fun h0 -> choice (p0 h0) in
      (* (choice which must always exists for strict subchains of hl) *)
      (forall h0. subchain o h0 hl /\ h0 <> hl ->
        let spr = supr h0 in
        subchain o h0 spr /\ h0 <> spr /\ ch spr
        by if exists u. p0 h0 u then true else
          false by upper_bound (subchain o) ch h0
          by forall h1. ch h1 -> subchain o h1 h0 || (false by p0 h0 h1)
      )
    so (* Construction of limit demon: first choose a strict subchain h of hl
          such that ang(h) = X, then a strict super-chain of h in chh,
          and apply the demon of h. *)
       let ch_by =
         fun s h0 -> exists x.
           subchain o h0 hl /\ maximum o h0 x /\ h0 <> hl /\ ang h0 = s in
       let dmn_l = fun s -> dmn_h (supr (choice (ch_by s))) s in
       forall h1. ch h1 -> dmn_witness g ang x0 h1 dmn_l
       by let dmn = dmn_h h1 in
         same_choices g ang h1 dmn dmn_l
       by forall h0 x. subchain o h0 h1 /\ maximum o h0 x /\ h1 <> h0 ->
         let s = ang h0 in dmn s = dmn_l s
       by let h_ = choice (ch_by s) in
         ch_by s h0 || (false by subchain o h0 hl so h0 <> hl)
       so ch_by s h_
       so let h2 = supr h_ in
         p0 h_ h2
       so let dmn2 = dmn_h h2 in
         dmn_witness g ang x0 h2 dmn2 /\ dmn_witness g ang x0 h1 dmn
       so if subchain o h2 h1
         then same_choices g ang h2 dmn2 dmn
           by dmn_witness g ang x0 h2 dmn
         else same_choices g ang h1 dmn dmn2
           by subchain o h1 h2
           so dmn_witness g ang x0 h1 dmn2

  lemma u_acc_by_step : forall g ang h,x0:'a.
    ("induction" tr_ext g.progress (u_acc_step g ang) ((=) x0) h) ->
    u_acc g ang x0 h

  clone Uacc with goal u_acc_base,
    goal u_acc_next,
    goal u_acc_lim,
    goal u_acc_sup,
    goal u_acc_by_step,
    goal u_acc_rebuild

end

module WinAltProof

  use import game.Game
  use import fn.Fun
  use import ho_set.Set
  use import ho_set.SetBigOps
  use import order.LimUniq
  use import order.SubChain
  use import transfinite.ExtensionDet
  use import transfinite.Transport
  use import Uacc

  (* Winning -> no losing u-acc: by contradiction, suppose there is one.
     1) Consider a demon that get to the losing history,
        enforcing a loop if possible.
     2) The losing history must be maximal.
     3) There is a winning history, and since it is subchain of the losing one,
        the possible winning conditions show that it must be maximal as well
     4) The losing/winning history are equal, which is a contradiction
        since the loop is enforced. *)
  lemma u_acc_losing_1 : forall g:game 'a,ang x0 win h.
    winning_strat g x0 win ang /\ u_acc g ang x0 h ->
    not (lose_at g ang win h
      so let o = g.progress in let ex = (=) x0 in let s = sup o h in
        maximum o h s
      so let a = ang h in
        exists dmn. let st = step g ang dmn in
          tr_ext o st ex h /\ (g.transition s a /\ a s -> dmn a = s)
      so maximum (subchain o) (tr_ext o st ex) h
      so win_against g x0 win ang dmn
      so exists h0. tr_ext o st ex h0 /\ win_at g win ang dmn h0
      so subchain o h0 h
      so maximum (subchain o) (tr_ext o st ex) h0
    )

  (* no losing u-acc -> winning: take any demon, and consider the maximum
       history hl.
     1) If winning at hl, done.
     2) hl has a sup (max because it is maximum), hence one strategy
        fails or a loop is created.
     3) since there are no losing u-acc, there must be a winning state
        within hl.
     4) the portion of hl up to that winning state is an effective witness. *)
  lemma u_acc_losing_2 : forall g:game 'a,ang x0 win.
    (forall h. u_acc g ang x0 h -> not lose_at g ang win h) ->
    winning_strat g x0 win ang
    by forall dmn. win_against g x0 win ang dmn
    by let o = g.progress in let st = step g ang dmn in let ex = (=) x0 in
      let ch = tr_ext o st ex in
      chain (subchain o) ch /\ ch ex
    so let hl = bigunion ch in
      maximum (subchain o) ch hl
    so if win_at g win ang dmn hl then true else
      let s = sup o hl in
      (maximum o hl s
       by supremum o hl s so hl s || (false by ch (add hl s)))
    so not lose_at g ang win hl
    so (let a = ang hl in g.transition s a -> a s
      by let d = dmn a in
        a d so o s d so o d s by hl d by ch (add hl d) by st hl d)
    so exists u. hl u /\ win u
    so let hw = fun s -> hl s /\ o s u in
      subchain o hw hl
    so maximum o hw u
    so subchain o ex hw || (false by subchain o hw ex)
    so tr_ext o st ex hw
    so win_at g win ang dmn hw

  (* no losing strong u-acc -> winning: simply show that if there
     is a losing u-acc, there is one which is strongly u-acc.
     We obtain it by minimality (e.g well-foundedness) *)
  lemma u_acc_losing_3 : forall g:game 'a,ang x0 win.
    (forall h. strong_u_acc g ang x0 h -> not lose_at g ang win h) ->
    winning_strat g x0 win ang
    by forall h. u_acc g ang x0 h /\ lose_at g ang win h -> false
    by let o = g.progress in let ex = (=) x0 in
      exists dmn. let st = step g ang dmn in tr_ext o st ex h
    so let s0 = fun h -> lose_at g ang win h /\ tr_ext o st ex h in
      subset s0 (tr_ext_det o st ex) /\ s0 h
    so let h2 = inf (subchain o) s0 in minimum (subchain o) s0 h2
    so strong_u_acc g ang x0 h2
    by let ust = u_acc_step g ang in
      transport_criterion o ust ex h2
    by forall h_ x_. subchain o ex h_ /\ subchain o (add h_ x_) h2 /\
      upper_bound o h_ x_ /\ not h_ x_ -> ust h_ x_
      by (st h_ x_ by transport_criterion o st ex h2)
      so subchain o h_ h2
      so if ust h_ x_ then true else false
      by let s = sup o h_ in
        let a = ang h_ in
        h_ s
      so g.transition s a
      so a s /\ (maximum o h_ s by supremum o h_ s)
      so lose_at g ang win h_
      so h2 x_
      so subchain o h2 h_ by s0 h_ by tr_ext o st ex h_

  lemma win_strat_from_victory_invariant : forall g:game 'a,ang inv start win.
    victory_invariant g start win inv ->
    winning_cause g win inv ang ->
    uniform_winning_strat g start win ang
    by forall x. start x -> winning_strat g x win ang
    by forall h. strong_u_acc g ang x h /\ lose_at g ang win h -> false
    by let o = g.progress in
      let ust = u_acc_step g ang in let ex = (=) x in
      ((forall a b c h. a = o /\ b = ust /\ c = ex ->
          ("induction" tr_ext a b c h) -> not inhabited (inter h win) -> inv h)
        by (forall h x.
          (not inhabited (inter h win) -> inv h) /\ ust h x
          /\ not inhabited (inter (add h x) win) ->
          next_hist inv h x by forall y. inter h win y -> false
            by inter (add h x) win y)
        /\ (forall ch h. let hl = bigunion ch in
          not inhabited (inter hl win) /\ ch h -> not inhabited (inter h win)
          by forall y. inter h win y -> false by inter hl win y
        )
      )

  lemma victory_invariant_from_win_strat_both :
    forall g:game 'a,ang start win bl.
    uniform_winning_strat g start win ang ->
    let inv = if bl then u_acc_s g ang start else strong_u_acc_s g ang start in
    victory_invariant g start win inv
    by let o = g.progress in
    (forall h x. inv h /\ not inhabited (inter h win) /\ maximum o h x ->
      exists a. g.transition x a /\ not a x /\ subset a (next_hist inv h)
      by a = ang h
      so not lose_at g ang win h /\ (forall x. h x -> not win x)
      so g.transition x a /\ not a x
      so forall y. a y -> inv (add h y)
      by u_acc_step g ang h y
    ) /\ (forall h x. inv h /\ supremum o h x -> inv (add h x)
      by if h x then sext h (add h x) else u_acc_step g ang h x
    ) /\ (forall ch. subset ch inv /\ chain (subchain o) ch /\ inhabited ch ->
      let hl = bigunion ch in
      inv hl
      by let inv_x = if bl then u_acc g ang else strong_u_acc g ang in
         (forall h x. inv_x x h -> minimum o h x)
      so exists h0. ch h0
      so exists x. start x /\ inv_x x h0
      so (forall h. ch h -> inv_x x h
        by exists y. inv_x y h
        so x = y
        by (minimum o h x by subchain o h0 h)
        \/ (minimum o h0 y by subchain o h h0)
      )
    )

  use import choice.Choice

  lemma victory_invariant_ok_1 : forall g:game 'a,inv start win.
    victory_invariant g start win inv ->
      have_uniform_winning_strat g start win
      by let o = g.progress in
        let covered = fun h a -> let m = sup o h in
          g.transition m a /\ not a m /\ subset a (next_hist inv h) in
        let ang = fun h -> choice (covered h) in
        winning_cause g win inv ang
      by forall h x. inv h /\ maximum o h x /\ not inhabited (inter h win) ->
        let a = ang h in
        covered h a
        by exists a. covered h a
        by g.transition x a /\ not a x /\ subset a (next_hist inv h)

  lemma victory_invariant_ok_2 : forall g:game 'a,start win.
    have_uniform_winning_strat g start win ->
    exists inv. victory_invariant g start win inv
    by exists ang. uniform_winning_strat g start win ang
      /\ inv = u_acc_s g ang start

  clone WinAlt with goal u_acc_losing,
    goal strong_u_acc_losing,
    goal victory_invariant_ok,
    goal win_strat_from_victory_invariant,
    goal victory_invariant_from_win_strat_1,
    goal victory_invariant_from_win_strat_2

end

module InvExtraProof

  use import game.Game
  use import ho_set.Set
  use import ho_set.SetBigOps
  use import ho_rel.RelSet
  use import order.Ordered
  use import order.Chain
  use import InvExtraDef
  use import Uacc
  use import WinAlt
  use import transfinite.ExtensionDef

  lemma victory_inv_span : forall g:game 'a,start win inv.
    let sg = span_game g in
    (victory_invariant g start win inv <->
      victory_invariant sg start win inv)
    by forall x a. g.transition x a -> sg.transition x a
    by related subset (g.transition x) a

  lemma cropping_access : forall g:game 'a,start win ang inv.
    let sg = span_game g in
    victory_invariant g start win inv /\ winning_cause sg win inv ang ->
    let nang = crop_ang inv ang in
    let ninv = strong_u_acc_s sg nang start in
    (subset ninv inv by forall h. ninv h -> inv h
      by exists u. start u /\ strong_u_acc sg nang u h
      so (forall a b c h. a = g.progress /\ b = u_acc_step sg nang ->
        c = (=) u -> ("induction" tr_ext a b c h) -> inv h)
    ) && (victory_invariant g start win ninv
      by winning_cause sg win inv nang
      by forall h x.
        inv h /\ maximum g.progress h x /\ not inhabited (inter h win) ->
        nang h = ang h by sext (nang h) (ang h)
    )

  lemma cropping : forall g:game 'a,start win inv.
    victory_invariant g start win inv ->
    let o = g.progress in let i = crop o win inv in
    victory_invariant g start win i
    by (forall h x. inv h /\ not inhabited (inter h win) /\ maximum o h x ->
      exists a. g.transition x a /\ not a x /\ subset a (next_hist i h)
       by g.transition x a /\ not a x /\ subset a (next_hist inv h)
       so forall y. a y -> let hy = add h y in i hy
       by forall z. inter hy win z -> maximum o hy z
       by y = z \/ (false by inter h win z)
       so forall z. hy z -> o z y by y = z \/ h z /\ o x y
    ) /\ (forall ch. subset ch i /\ chain (subchain o) ch /\ inhabited ch ->
      let hl = bigunion ch in i hl
      by forall z. inter hl win z -> maximum o hl z
      by forall t. hl t -> o t z
      by (exists h. ch h /\ h z /\ h t
        so maximum o h z
      ) by (exists h1 h2. ch h1 /\ h1 z /\ ch h2 /\ h2 t
        so (h2 z by subchain o h1 h2) \/ (h1 t by subchain o h2 h1)
      )
    ) /\ (forall h x. i h /\ supremum o h x -> let hx = add h x in i hx
      by forall z. inter hx win z -> maximum o hx z
      by not (x <> z so maximum o h z)
    )

  clone InvExtra with goal cropping,
    goal cropping_access

end


Generated by why3doc 0.90+git