File: induction.mlw

package info (click to toggle)
why3 1.8.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 45,028 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 (100 lines) | stat: -rw-r--r-- 1,868 bytes parent folder | download | duplicates (5)
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

(** Various ways of proving

            p 0
            p 1
            forall n: int. 0 <= n -> p n -> p (n+2)
            ---------------------------------------
            forall n: int. 0 <= n -> p n

    by induction using theories int.SimpleInduction or
    int.Induction or lemma functions.

*)

theory Hyps
  use export int.Int

  predicate p int

  axiom H0: p 0
  axiom H1: p 1
  axiom H2: forall n: int. 0 <= n -> p n -> p (n + 2)

end

(** {2 With a simple induction} *)

module Induction1
  use Hyps

  predicate pr (k: int) = p k && p (k+1)
  clone int.SimpleInduction
    with predicate p = pr, lemma base, lemma induction_step

  goal G: forall n: int. 0 <= n -> p n

end

(** {2 With a strong induction} *)

module Induction2
  use Hyps

  clone int.Induction
    with predicate p = p, constant bound = zero

  goal G: forall n: int. 0 <= n -> p n

end

(** {2 With a recursive lemma function} *)

module LemmaFunction1
  use Hyps

  let rec lemma ind (n: int) requires { 0 <= n} ensures { p n }
    variant { n }
    = if n >= 2 then ind (n-2)

  (** no need to write the following goal, that's just a check this is
      now proved *)
  goal G: forall n: int. 0 <= n -> p n

end

(** {2 With a while loop} *)

module LemmaFunction2
  use Hyps
  use ref.Ref

  let lemma ind (n: int) requires { 0 <= n} ensures { p n }
    =
    let k = ref n in
    while !k >= 2 do
      invariant { 0 <= !k && (p !k -> p n) } variant { !k }
      k := !k - 2
    done

  goal G: forall n: int. 0 <= n -> p n

end

(** {2 With an ascending while loop} *)

module LemmaFunction3
  use Hyps
  use ref.Ref

  let lemma ind (n: int) requires { 0 <= n} ensures { p n }
    =
    let k = ref 0 in
    while !k <= n - 2 do
      invariant { 0 <= !k <= n && p !k && p (!k + 1) } variant { n - !k }
      k := !k + 2
    done

  goal G: forall n: int. 0 <= n -> p n

end