summaryrefslogtreecommitdiff
path: root/assignment8/qs.pvs
blob: 086321a8484e4ebaf3bf734142f3115253849a78 (plain) (blame)
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
my_list_induction[X:TYPE] : THEORY
BEGIN
   less(l1,l2: list[X]) : bool = length(l1) < length(l2)

   less_wf: LEMMA well_founded?(less) % :-)

   list_length_induction :LEMMA % :-)
        (FORALL (p:pred[list[X]]):
            (FORALL (g:list[X]):
                (FORALL (s:list[X]):
                    less(s,g) IMPLIES p(s))
                        IMPLIES p(g))
            IMPLIES (FORALL (l:list[X]): p(l)))

END my_list_induction

my_list_props[X:TYPE] : THEORY
BEGIN
    occ(x:X,l:list[X]) : RECURSIVE nat =
      CASES l
        OF null   : 0 ,
        cons(y,l) : IF x=y THEN occ(x,l)+1 ELSE occ(x,l) ENDIF
      ENDCASES
    MEASURE length(l)

    occ_nth: LEMMA
       FORALL(l:list[X]): FORALL(x:X): occ(x,l) > 0 IMPLIES 
          EXISTS(i:nat): i<length(l) AND nth(l,i) = x

    nth_occ: LEMMA
       FORALL(l:list[X]): FORALL(i:nat): i<length(l) IMPLIES occ(nth(l,i),l) > 0 

    perm?( l1,l2 : list[X]) : bool = FORALL(x:X): occ(x,l1) = occ(x,l2)

    perm_null: LEMMA % :-)
       FORALL(l:list[X]): perm?(null, l) IMPLIES l = null

    perm_commutative: LEMMA % :-)
       FORALL(l1,l2: list[X]):perm?(l1,l2) IMPLIES perm?(l2,l1)

    append_occ: LEMMA % :-)
       FORALL( l1,l2:list[X] ): FORALL(x:X): occ(x,append(l1,l2)) = occ(x,l1)+occ(x,l2)

    length_append: LEMMA % :-)
 	   FORALL( l1,l2:list[X] ):length(append(l1,l2)) = length(l1) + length(l2)

    nth_append: LEMMA % :-( to be done
       FORALL( l1,l2:list[X] ): FORALL(i:nat): i < length(l1)+length(l2) IMPLIES
           nth(append(l1,l2),i) = IF i < length(l1) THEN nth(l1,i) ELSE nth(l2,i-length(l1)) ENDIF

END my_list_props


SPLIT : THEORY
BEGIN
    IMPORTING my_list_props

    split (m: nat, l : list[nat]) : RECURSIVE [list[nat], list[nat]] =
        CASES l OF
            null        : (null, null),
            cons(h,t)   : LET
                            (l,r) = split (m, t)
                          IN
                            IF h < m
                            THEN (cons(h,l),r)
                            ELSE (l,cons(h,r))
                            ENDIF
        ENDCASES
    MEASURE (length(l))

    split_length: LEMMA % :-)
       FORALL( m:nat, l:list[nat] ): LET s = split(m,l) IN length(l) = length(s`1) + length(s`2)

    split_occ: LEMMA % :-)
       FORALL( n: nat, l:list[nat] ): LET s = split(n, l) IN FORALL(x:nat):occ(x,l) = occ(x,s`1)+occ(x,s`2)

    upb( g:nat, l:list[nat] ): bool =
       FORALL(i:nat): i < length(l) IMPLIES nth(l,i) < g

    lwb( s:nat, l:list[nat] ): bool =
       FORALL(i:nat): i < length(l) IMPLIES NOT nth(l,i) < s

    split_lwb_upb: LEMMA % :-( to be done
       FORALL( m:nat, l:list[nat] ): LET s = split(m,l) IN upb(m,s`1) AND lwb(m,s`2)

END SPLIT

QS : THEORY
BEGIN
	IMPORTING SPLIT
    qs (l : list[nat]) : RECURSIVE list[nat] =
        CASES l OF
            null        : null,
            cons(h,t)   : LET
                            (l,r) = split (h, t)
                          IN
                            append(qs(l),cons(h,qs(r)))
        ENDCASES
    MEASURE (length(l))

END QS

SORTED: THEORY
BEGIN
    IMPORTING my_list_props[nat]
    IMPORTING SPLIT

    sorted?(l:list[nat]) : bool = 
        FORALL (i,j: nat): i < j AND j < length(l) IMPLIES nth(l,i) <= nth(l,j)

    sorted_append: LEMMA % :-( to be done
       FORALL( m:nat, l1,l2:list[nat] ): 
          sorted?(l1) AND sorted?(l2) and upb(m,l1) AND lwb(m,l2)
            IMPLIES sorted?(append(l1,l2))
END SORTED

QS_props : THEORY
BEGIN
    IMPORTING QS, SORTED
    IMPORTING my_list_props[nat], my_list_induction[nat]

    qs_perm: LEMMA % :-( to be done
       FORALL(l:list[nat]):perm?(qs(l),l)

    occ_upb: LEMMA % :-) 
        FORALL( n: nat, l:list[nat] ): upb(n,l) IMPLIES 
            (FORALL(x:nat):occ(x,l) > 0 IMPLIES x < n) 

    occ_lwb: LEMMA % :-)
        FORALL( n: nat, l:list[nat] ): lwb(n,l) IMPLIES 
            (FORALL(x:nat):occ(x,l) > 0 IMPLIES NOT x < n) 

    upb_perm: LEMMA % :-)
    	FORALL(l, lp: list[nat]): perm?(l,lp) IMPLIES
	        FORALL(n:nat): upb(n,l) IMPLIES upb(n,lp)

    lwb_perm: LEMMA % :-)
    	FORALL(l, lp: list[nat]): perm?(l,lp) IMPLIES
   	        FORALL(n:nat): lwb(n,l) IMPLIES lwb(n,lp)

    qs_sorted :LEMMA % :-( to be done
        FORALL (l:list[nat]): sorted?(qs(l))

%    tl : VAR list[nat]

%    test : LEMMA
%        qs ((:4,3,6,2,5:)) = tl


END QS_props