File: bag.mlw

package info (click to toggle)
why3 1.8.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 45,020 kB
  • sloc: xml: 185,443; ml: 111,224; ansic: 3,998; sh: 2,578; makefile: 2,568; java: 865; python: 720; javascript: 290; lisp: 205; pascal: 173
file content (130 lines) | stat: -rw-r--r-- 3,389 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130

(** {1 Multisets (aka bags)} *)

module Bag

  use int.Int

  type bag 'a

  (** whatever `'a`, the type `bag 'a` is always infinite *)
  meta "infinite_type" type bag

  (** the most basic operation is the number of occurrences *)

  function nb_occ (x: 'a) (b: bag 'a): int

  axiom occ_non_negative: forall b: bag 'a, x: 'a. nb_occ x b >= 0

  predicate mem (x: 'a) (b: bag 'a) = nb_occ x b > 0

  (** equality of bags *)

  predicate (==) (a b: bag 'a) =
    forall x:'a. nb_occ x a = nb_occ x b

  axiom bag_extensionality: forall a b: bag 'a. a == b -> a = b

  meta extensionality predicate (==)

  (** basic constructors of bags *)

  function empty_bag: bag 'a

  axiom occ_empty: forall x: 'a. nb_occ x empty_bag = 0

  lemma is_empty: forall b: bag 'a.
    (forall x: 'a. nb_occ x b = 0) -> b = empty_bag

  function singleton (x: 'a) : bag 'a

  axiom occ_singleton: forall x y: 'a.
    (x = y /\ (nb_occ y (singleton x)) = 1) \/
    (x <> y /\ (nb_occ y (singleton x)) = 0)
    (* FIXME? nb_occ y (singleton x) = if x = y then 1 else 0 *)

  lemma occ_singleton_eq:
    forall x y: 'a. x = y -> nb_occ y (singleton x) = 1
  lemma occ_singleton_neq:
    forall x y: 'a. x <> y -> nb_occ y (singleton x) = 0

  (** union *)

  function union (bag 'a) (bag 'a) : bag 'a

  axiom occ_union:
    forall x: 'a, a b: bag 'a.
    nb_occ x (union a b) = nb_occ x a + nb_occ x b

  lemma Union_comm: forall a b: bag 'a. union a b = union b a

  lemma Union_identity: forall a: bag 'a. union a empty_bag = a

  lemma Union_assoc:
    forall a b c: bag 'a. union a (union b c) = union (union a b) c

  lemma bag_simpl_right:
    forall a b c: bag 'a. union a b = union c b -> a = c

  lemma bag_simpl_left:
    forall a b c: bag 'a. union a b = union a c -> b = c

  (** add operation *)

  function add (x: 'a) (b: bag 'a) : bag 'a = union (singleton x) b

  lemma occ_add_eq:
    forall b: bag 'a, x y: 'a.
    x = y -> nb_occ y (add x b) = nb_occ y b + 1

  lemma occ_add_neq: forall b: bag 'a, x y: 'a.
    x <> y -> nb_occ y (add x b) = nb_occ y b

  (** cardinality *)

  function card (bag 'a): int

  axiom Card_nonneg: forall x: bag 'a. card x >= 0
  axiom Card_empty: card (empty_bag: bag 'a) = 0
  axiom Card_zero_empty: forall x: bag 'a. card x = 0 -> x = empty_bag

  axiom Card_singleton: forall x:'a. card (singleton x) = 1
  axiom Card_union: forall x y: bag 'a. card (union x y) = card x + card y
  lemma Card_add: forall x: 'a, b: bag 'a. card (add x b) = 1 + card b

  (** difference *)

  use int.MinMax

  function diff (bag 'a) (bag 'a) : bag 'a

  axiom Diff_occ: forall b1 b2: bag 'a, x:'a.
    nb_occ x (diff b1 b2) = max 0 (nb_occ x b1 - nb_occ x b2)

  lemma Diff_empty_right: forall b: bag 'a. diff b empty_bag = b
  lemma Diff_empty_left: forall b: bag 'a. diff empty_bag b = empty_bag

  lemma Diff_add: forall b: bag 'a, x:'a. diff (add x b) (singleton x) = b

  lemma Diff_comm:
    forall b b1 b2: bag 'a. diff (diff b b1) b2 = diff (diff b b2) b1

  lemma Add_diff: forall b: bag 'a, x:'a.
    mem x b -> add x (diff b (singleton x)) = b

  (** intersection *)

  function inter (a b: bag 'a) : bag 'a

  axiom inter:
    forall x: 'a, a b: bag 'a.
    nb_occ x (inter a b) = min (nb_occ x a) (nb_occ x b)

  (** arbitrary element *)

  function choose (b: bag 'a) : 'a

  axiom choose_mem: forall b: bag 'a.
    empty_bag <> b -> mem (choose b) b

end