why3doc index index
(* Basic arrow definitions *) module Fun use export HighOrd predicate ext (f g:'a -> 'b) = forall x. f x = g x predicate equalizer (a:'a -> bool) (f g:'a -> 'b) = forall x. a x -> f x = g x function compose (g:'b -> 'c) (f:'a -> 'b) : 'a -> 'c = fun x -> g (f x) function rcompose (f:'a -> 'b) (g:'b -> 'c) : 'a -> 'c = compose g f function id : 'a -> 'a = fun x -> x function const (x:'b) : 'a -> 'b = fun _ -> x function fst (x:('a,'b)) : 'a = let (x,_) = x in x function snd (x:('a,'b)) : 'b = let (_,x) = x in x function flip (f:'a -> 'b -> 'c) : 'b -> 'a -> 'c = fun x y -> f y x function update (f:'a -> 'b) (x:'a) (y:'b) : 'a -> 'b = fun z -> if z = x then y else f z function ([<-]) (f:'a -> 'b) (x:'a) (y:'b) : 'a -> 'b = update f x y end (* Proof done via cloning+replacing axioms by goals *) (* Functional extensionality. *) module FunExt "W:non_conservative_extension:N" (* => FunProofs *) use export Fun axiom extensionality : forall f g:'a -> 'b. ext f g -> f = g let extensional (f g:'a -> 'b) : unit requires { ext f g } ensures { f = g } = () end (* Evident category properties of functions. *) module FunCategory "W:non_conservative_extension:N" (* => FunProofs *) use export Fun axiom assoc : forall f:'a -> 'b,g,h:'c -> 'd. compose (compose h g) f = compose h (compose g f) axiom neutral : forall f:'a -> 'b. compose f id = f = compose id f end (* Proofs of above Fun modules *) module FunProofs use import Fun predicate hack (f g h:'a -> 'b) = f = g = h lemma ext : forall f g:'a -> 'b. ext f g -> f = g by hack f (fun x -> (fun y -> y) (f x)) g lemma assoc : forall f:'a -> 'b,g,h:'c -> 'd. ext (compose (compose h g) f) (compose h (compose g f)) lemma neutral : forall f:'a -> 'b. ext (compose f id) f /\ ext (compose id f) f clone FunExt with goal extensionality clone FunCategory with goal assoc, goal neutral end (* Basic definition on sets-as-arrows *) module Set use import Fun type set 'a = 'a -> bool predicate subset (a b:set 'a) = forall x. a x -> b x predicate inhabited (s:set 'a) = exists x. s x predicate sext (a b:set 'a) = forall x. a x <-> b x lemma sext_is_ext : forall a b:set 'a. sext a b -> ext a b function neg (s:set 'a) : set 'a = fun x -> not (s x) function union (a b:set 'a) : set 'a = fun x -> a x \/ b x function inter (a b:set 'a) : set 'a = fun x -> a x /\ b x function diff (a b:set 'a) : set 'a = inter a (neg b) constant all : set 'a = fun _ -> true constant none : set 'a = fun _ -> false function sing (x:'a) : set 'a = (=) x function add (s:set 'a) (x:'a) : set 'a = fun y -> s y \/ x = y function remove (s:set 'a) (x:'a) : set 'a = fun y -> s y /\ y <> x end (* Some usual big operators on sets. *) module SetBigOps use import Set function bigunion (c:set (set 'a)) : set 'a = fun x -> exists s. c s /\ s x function biginter (c:set (set 'a)) : set 'a = fun x -> forall s. c s -> s x end (* Basic definition on relations-as-arrows *) module Rel use import Fun type rel 'a 'b = 'a -> 'b -> bool type erel 'a = rel 'a 'a predicate rext (r1 r2:rel 'a 'b) = forall x y. r1 x y <-> r2 x y predicate reflexive (r:erel 'a) = forall x. r x x predicate symetric (r:erel 'a) = forall x y. r x y -> r y x predicate transitive (r:erel 'a) = forall x y z. r x y /\ r y z -> r x z predicate antisymetric (r:erel 'a) = forall x y. r x y /\ r y x -> x = y predicate total (r:erel 'a) = forall x y. r x y \/ r y x predicate det_related (r:rel 'a 'b) (x:'a) = forall y z. r x y /\ r x z -> y = z predicate deterministic (r:rel 'a 'b) = forall x. det_related r x predicate preorder (r:erel 'a) = reflexive r /\ transitive r predicate order (r:erel 'a) = preorder r /\ antisymetric r predicate equivalence (r:erel 'a) = preorder r /\ symetric r inductive acc_on (erel 'a) ('a -> bool) 'a = | Acc : forall r s,x:'a. s x /\ (forall y. s y /\ r y x -> acc_on r s y) -> acc_on r s x predicate wf_on (r:erel 'a) (s:'a -> bool) = forall x. s x -> acc_on r s x constant id : rel 'a 'a = (=) function of_func (f:'a -> 'b) : rel 'a 'b = fun x y -> y = f x function compose (r1:rel 'a 'b) (r2:rel 'b 'c) : rel 'a 'c = fun x z -> exists y. r1 x y /\ r2 y z function reverse (r:rel 'a 'b) : rel 'b 'a = flip r end (* Relational extensionality. *) module RelExt "W:non_conservative_extension:N" (* => RelProofs *) use export Rel axiom extensionality : forall r1 r2:rel 'a 'b. rext r1 r2 -> r1 = r2 end (* Evident category properties of relations. *) module RelCategory "W:non_conservative_extension:N" (* => RelProofs *) use export Rel axiom assoc : forall r1:rel 'a 'b,r2,r3:rel 'c 'd. compose r1 (compose r2 r3) = compose (compose r1 r2) r3 axiom reverse_antimorphism : forall r1:rel 'a 'b,r2:rel 'b 'c. compose (reverse r2) (reverse r1) = reverse (compose r1 r2) axiom reverse_antimorphism_id : reverse id = (id:erel 'a) axiom reverse_involution : forall r:rel 'a 'b. reverse (reverse r) = r axiom neutral : forall r:rel 'a 'b. compose r id = r = compose id r end (* Relation product. *) module RelProduct use export Rel predicate rprod (r1:rel 'a 'b) (r2:rel 'c 'd) (x:('a,'c)) (y:('b,'d)) = let (xa,xc) = x in let (yb,yd) = y in r1 xa yb /\ r2 xc yd end (* Elements related to a set. *) module RelSet use import Set use export Rel predicate related (r:rel 'a 'b) (s:set 'a) (y:'b) = exists x. s x /\ r x y predicate i_related (r:rel 'a 'b) (s:set 'b) (x:'a) = exists y. s y /\ r x y end module RelProofs use import FunExt use import Rel lemma extensionality : forall r1 r2:rel 'a 'b. rext r1 r2 -> r1 = r2 by ext r1 r2 by forall x. ext (r1 x) (r2 x) predicate (==) (x y:rel 'a 'b) = rext x y meta rewrite_def predicate (==) meta rewrite_def predicate rext meta rewrite_def function compose lemma assoc : forall r1:rel 'a 'b,r2,r3:rel 'c 'd. compose r1 (compose r2 r3) == compose (compose r1 r2) r3 lemma reverse_antimorphism : forall r1:rel 'a 'b,r2:rel 'b 'c. compose (reverse r2) (reverse r1) == reverse (compose r1 r2) lemma reverse_antimorphism_id : reverse id == (id:erel 'a) lemma reverse_involution : forall r:rel 'a 'b. reverse (reverse r) == r lemma neutral : forall r:rel 'a 'b. compose r id == r == compose id r clone RelExt with goal extensionality clone RelCategory with goal assoc, goal reverse_antimorphism, goal reverse_antimorphism_id, goal reverse_involution, goal neutral end module SubsetOrder "W:non_conservative_extension:N" (* => SetProofs *) use export Set use import Rel axiom subset_order : order (subset:erel (set 'a)) end module SetProofs use import FunExt use import Set lemma anti_subset : forall s1 s2:set 'a. subset s1 s2 /\ subset s2 s1 -> sext s1 s2 clone SubsetOrder with goal subset_order end module Image use import Fun use import Set predicate image (f:'a -> 'b) (s:set 'a) (y:'b) = exists x. s x /\ f x = y predicate preimage (f:'a -> 'b) (s:set 'b) (x:'a) = s (f x) end module PartialFun "W:non_conservative_extension:N" (* => PartialFunInstance *) use import Fun use import Set type pfun 'a 'b (* TODO/FIXME: seems weird that it is necessary to separate the function/val definition so that they can be used with the dot notation. *) function domain (pfun 'a 'b) : set 'a function eval (pfun 'a 'b) : 'a -> 'b val ghost function of_fun (f:{'a -> 'b}) : {pfun 'a 'b} ensures { result.domain = all /\ result.eval = f } val ghost function restrict (p:set {'a}) (f:{pfun 'a 'b}) : {pfun 'a 'b} ensures { result.domain = inter p f.domain } ensures { forall x. result.domain x -> result.eval x = f.eval x } val ghost function extends (f g:{pfun 'a 'b}) : {pfun 'a 'b} ensures { result.domain = union f.domain g.domain } ensures { forall x. g.domain x -> result.eval x = g.eval x } ensures { forall x. f.domain x /\ not g.domain x -> result.eval x = f.eval x } val ghost function join (f g:{pfun 'a 'b}) : {pfun 'a 'b} requires { equalizer (inter f.domain g.domain) f.eval g.eval } ensures { result.domain = union f.domain g.domain } ensures { forall x. g.domain x -> result.eval x = g.eval x } ensures { forall x. f.domain x -> result.eval x = f.eval x } val ghost function psing (x:{'a}) (y:{'b}) : {pfun 'a 'b} ensures { result.domain = sing x } ensures { result.eval x = y } val ghost function padd (f:{pfun 'a 'b}) (x:{'a}) (y:{'b}) : {pfun 'a 'b} ensures { result.domain = add f.domain x } ensures { result.eval x = y } ensures { forall x0. result.domain x0 /\ x <> x0 -> result.eval x0 = f.eval x0 } val ghost function premove (f:{pfun 'a 'b}) (x:{'a}) : {pfun 'a 'b} ensures { result.domain = remove f.domain x } ensures { forall x. result.domain x -> result.eval x = f.eval x } predicate pext (f g:pfun 'a 'b) = f.domain = g.domain && equalizer f.domain f.eval g.eval axiom extensional : forall f g:pfun 'a 'b. pext f g -> f = g predicate subfun (f g:pfun 'a 'b) = subset f.domain g.domain && equalizer f.domain f.eval g.eval end module PartialFunInstance use import FunExt use import Set type o 'a = N | S 'a type pfun 'a 'b = 'a -> o 'b let function dummy () : 'b requires { false } = absurd function domain (f:pfun 'a 'b) : set 'a = fun x -> match f x with N -> false | _ -> true end function eval (f:pfun 'a 'b) : 'a -> 'b = fun x -> match f x with N -> dummy () | S u -> u end let ghost function of_fun (f:{'a -> 'b}) : {pfun 'a 'b} ensures { sext result.domain all } ensures { ext result.eval f } = fun x -> S (f x) let ghost function restrict (p:set {'a}) (f:{pfun 'a 'b}) : {pfun 'a 'b} ensures { sext result.domain (inter p f.domain) } = fun x -> if p x then f x else N let ghost function extends (f g:{pfun 'a 'b}) : {pfun 'a 'b} ensures { sext result.domain (union f.domain g.domain) } = fun x -> match g x with S u -> S u | N -> f x end let ghost function psing (x:{'a}) (y:{'b}) : {pfun 'a 'b} = restrict ({sing} x) (of_fun ({const} y)) let ghost function padd (f:{pfun 'a 'b}) (x:{'a}) (y:{'b}) : {pfun 'a 'b} = extends f (psing x y) let ghost function premove (f:{pfun 'a 'b}) (x:{'a}) : {pfun 'a 'b} = restrict ({remove} f.domain x) f lemma extensional : forall f g:pfun 'a 'b. f.domain = g.domain /\ equalizer f.domain f.eval g.eval -> f = g by ext f g by forall x. f x = g x by match f x with | N -> not g.domain x | _ -> g.domain x so g.eval x = f.eval x end clone PartialFun with type pfun 'a 'b = pfun 'a 'b, function domain = domain, function eval = eval, val of_fun = of_fun, val restrict = restrict, val extends = extends, val join = extends, val psing = psing, val padd = padd, val premove = premove, goal extensional end module SubFunOrder use export PartialFun use import Rel lemma subfun_order : order (subfun:erel (pfun 'a 'b)) by forall f g:pfun 'a 'b. subfun f g /\ subfun g f -> f = g by pext f g end
Generated by why3doc 0.90+git