File: matrix.why

package info (click to toggle)
why 2.26%2Bdfsg-2%2Bsqueeze1
  • links: PTS, VCS
  • area: main
  • in suites: squeeze
  • size: 19,796 kB
  • ctags: 19,175
  • sloc: ml: 115,078; java: 9,253; ansic: 4,757; makefile: 1,350; sh: 485; lisp: 3
file content (186 lines) | stat: -rw-r--r-- 5,792 bytes parent folder | download | duplicates (3)
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
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
(* ########################################################################## *)
(*                             Definitions of matrices                        *)
(*                         Frdric Gava (Universit Paris 12)                *)
(* ########################################################################## *)

(* ************************** *)
(* Definition of the matrices *)
(* ************************** *)

type 'a fmatrice


(* ****************************** *)
(* access and update of a matrice *)
(* ****************************** *)

logic mat_access : 'a fmatrice, int,int -> 'a
logic mat_update : 'a fmatrice, int,int,'a -> 'a fmatrice


(* *************** *)
(* axiom of update *)
(* *************** *)

axiom mat_access_update : 
  forall m : 'a fmatrice. forall i : int. forall j : int. forall v : 'a.
  mat_access(mat_update(m,i,j,v), i,j) = v

axiom access_update_neq : 
  forall m : 'a fmatrice. forall i1 : int. forall j1 : int. 
                          forall i2 : int. forall j2 : int.
			  forall v : 'a.
  (i1 <> i2) or (j1<>j2) -> mat_access(mat_update(m,i1,j1,v),i2,j2) = mat_access(m,i2,j2)


(* ********************** *)
(* size of row and column *)
(* ********************** *)

logic mat_size_row : 'a fmatrice -> int
logic mat_size_column : 'a fmatrice -> int


(* ************************************ *)
(* effective size of the row and column *)
(* ************************************ *)

parameter mat_size_row_ : 
  m:'a fmatrice ref -> {} int reads m { result=mat_size_row(m) }

parameter mat_size_column_ : 
  m:'a fmatrice ref -> {} int reads m { result=mat_size_column(m) }


(* *************************** *)
(* effective access and update *)
(* *************************** *)

parameter mat_get :
  m:'a fmatrice ref -> i:int -> j:int -> 
    { 0 <= i < mat_size_row(m) 
  and 0 <= j < mat_size_column(m)} 'a reads m { result = mat_access(m,i,j) }

parameter mat_set : 
  m:'a fmatrice ref -> i:int -> j:int -> v:'a -> 
    { 0 <= i < mat_size_row(m) 
  and 0 <= j < mat_size_column(m) } unit writes m { m = mat_update(m@,i,j,v) }


(* *********************************** *)
(* axioms on row and column and update *)
(* *********************************** *)

axiom mat_size_row_update :
  forall m:'a fmatrice. forall i:int. forall j:int. forall v:'a.
  mat_size_row(mat_update(m,i,j,v)) = mat_size_row(m)

axiom mat_size_column_update :
  forall m:'a fmatrice. forall i:int. forall j:int. forall v:'a.
  mat_size_column(mat_update(m,i,j,v)) = mat_size_column(m)



(* ########################################################################## *)
(*                   Multiplication of square matrices C=A*B                  *)
(* ########################################################################## *)


(* ******************** *)
(* size of the matrices *)
(* ******************** *)

logic N : int

axiom N_range : 1 <= N


(* ****************** *)
(* Usefull Predicates *)
(* ****************** *)

(*  sigma_mat_mult A B mini maxi i j === sigma_{r=mini}^{maxi} A[i,r]*B[r,j] *)
logic sigma_mat_mult : real fmatrice,real fmatrice,int,int,int,int -> real

axiom sigma_mat_mult_def_1 :
  forall A,B:real fmatrice. forall mini,maxi,i,j:int.
  maxi > mini -> sigma_mat_mult(A,B,mini,maxi,i,j) = 0.

axiom sigma_mat_mult_def_2 :
  forall A,B:real fmatrice. forall mini,maxi,i,j:int.
  mini < maxi -> 
    sigma_mat_mult(A,B,mini,maxi,i,j) = 
    sigma_mat_mult(A,B,mini,maxi-1,i,j) + 
      mat_access(A,i,maxi) * mat_access(B,maxi,j)

(* Part of C that have been completly calulated *)
predicate mat_mult_done(A:real fmatrice, B:real fmatrice,C:real fmatrice,iu:int,id:int,jl:int,jr:int) =
 forall i,j:int.  (iu<=i<id and jl<=j<jr) -> mat_access(C,i,j)=sigma_mat_mult(A,B,0,N-1,i,j)

(* Part of C that need to be calculated *)
predicate mat_mult_todo(C:real fmatrice,C':real fmatrice,iu:int,id:int,jl:int,jr:int) =
  forall i,j:int.  (iu<=i<id and jl<=j<jr) -> mat_access(C,i,j)=mat_access(C',i,j)

(* C=A*B *)  
predicate mat_mult(A:real fmatrice, B:real fmatrice,C:real fmatrice) =
  mat_mult_done(A,B,C,0,N,0,N)

(* ******************************** *)
(* Definition of the multiplication *)
(* ******************************** *)

let mult (A : real fmatrice ref)
         (B : real fmatrice ref)
	 (C : real fmatrice ref) =
{
     mat_size_row(A) = N
 and mat_size_row(B) = N
 and mat_size_row(C) = N
 and mat_size_column(A) = N
 and mat_size_column(B) = N
 and mat_size_column(C) = N
 and (forall x,y:int. 0<=x<N and 0<=y<N -> mat_access(C,x,y)=0.)
}
 init:
 let i=ref 0 in
  while !i<N do
   { invariant 
          0<=i<=N 
      and mat_mult_done(A,B,C,0,i,0,N) 
      and mat_mult_todo(C,C@init,i,N,0,N)
      and (mat_size_column(C) = mat_size_column(C@init)) 
      and (mat_size_row(C) = mat_size_row(C@init))
     variant N-i}
   let j=ref 0 in
    begin
     while !j<N do
     { invariant 
            0<=j<=N 
	and mat_mult_done(A,B,C,0,i,0,N)
	and mat_mult_todo(C,C@init,i+1,N,0,N) 
	and mat_mult_done(A,B,C,i,i+1,0,j)
	and mat_mult_todo(C,C@init,i,i+1,j,N)
        and (mat_size_column(C) = mat_size_column(C@init)) 
	and (mat_size_row(C) = mat_size_row(C@init))
       variant N-j }
      let r=ref 0 in
        while !r<N do
	{ invariant
	       0<=r<=N 
	   and mat_mult_done(A,B,C,0,i,0,N)
           and mat_mult_todo(C,C@init,i+1,N,0,N)
	   and mat_mult_done(A,B,C,i,i+1,0,j)
     	   and mat_mult_todo(C,C@init,i,i+1,j+1,N)
	   and (mat_access(C,i,j)=mat_access(C@init,i,j)+sigma_mat_mult(A,B,0,r-1,i,j))
           and (mat_size_column(C) = mat_size_column(C@init))
	   and (mat_size_row(C) = mat_size_row(C@init))
	  variant N-r}
	  mat_set C !i !j ((mat_get C !i !j) + ((mat_get A !i !r) * (mat_get B !r !j)));
	  r:=!r+1
	done;
       j:=!j+1
     done
    end;
   i:=!i+1
  done
  { mat_mult(A,B,C) }