File_descriptor_table Module Interface Specification

Informal Introduction

There is one file descriptor table for each user in the Unix system. A table
contains one entry for each open file. Files are identified by file descriptors.
An entry in a file descriptor table contains an index of the entry in the system
file table.

(0) CHARACTERISTICS

-type specified: fdtable

-features: deterministic, non-parameterized

-foreign types: global

(1) SYNTAX

ACCESS-PROGRAMS

Program Name
Arg#1Arg#2Arg#3Result Type
CREATEfdtable:VOint:Oint:V 
RELEASEfdtable:VOint:V   
DUPfdtable:VOint:V  int
EXISTSfdtable:Vint:V  bool
GETMINFREEfdtable:V    int
GETFILETABLEINDEXfdtable:Vint:V  int
GETMAXFDfdtable:V    int
ISFULLfdtable:V    bool

(2) CANONICAL TRACES

canonical(T) m,n:<int>; e[0]..e[m]:<int>; k[0]..k[n]:<int> ( i:<int> (0 i i n) [-1 m m n n < global::G_fdtable_size() 0 k[i] k[i] < global::G_filetable_size() (i < m e[i] < e[i + 1] k[e[i]] = 0 ) 0 e[0] e[m] < n k[e[m]] = 0 ]) [T = [CREATE(*, *1, k[i])]i=0..n.[RELEASE(*, e[i])]i=0..m ]

AUXILIARY FUNCTIONS

interrorval: <int>

interrorval() = -1

exists: <fdtable> × <int> <bool>

exists(T, d) =

ConditionValue
d < 0 d global::G_fdtable_size()false
d 0 d < global::G_fdtable_size() m,n:<int>; e[0]..e[m]:<int>; k[0]..k[n]:<int> (-1 m m n 0 e[0] i:<int> (0 i i < m) [e[i] < e[i + 1]] i:<int> (0 i i n) [k[i] 0]) [T = [CREATE(*, *1, k[i])]i=0..n.[RELEASE(*, e[i])]i=0..m n d i:<int> (0 i i m) [d e[i]]]

fdtablesize: <fdtable> <int>

fdtablesize(T) =

ConditionValue
T = _ 0
! m,n:<int>; e[0]..e[m]:<int>; k[0]..k[n]:<int> (-1 m m n 0 e[0] i:<int> (0 i i < m) [e[i] < e[i + 1]] i:<int> (0 i i n) [k[i] 0]) [T = [CREATE(*, *1, k[i])]i=0..n.[RELEASE(*, e[i])]i=0..m ]n - m

isfull: <fdtable> <bool>

isfull(T) = fdtablesize(T) = global::G_fdtable_size()

getminfree: <fdtable> <int>

getminfree(T) =

ConditionValue
isfull(T)interrorval()
¬isfull(T)d0 where d0:<int> (0 d0 d0 < global::G_fdtable_size()) [¬exists(T, d0) d:<int> [d < d0 exists(T, d)]]

getfiletableindex: <fdtable> × <int> <int>

getfiletableindex(T, d) =

ConditionValue
¬exists(T, d)interrorval()
exists(T, d)k[d] where m,n:<int>; e[0]..e[m]:<int>; k[0]..k[n]:<int> (-1 m m < n 0 e[0] i:<int> (0 i i < m) [e[i] < e[i + 1]] i:<int> (0 i i n) [k[i] 0]) [T = [CREATE(*, *1, k[i])]i=0..n.[RELEASE(*, e[i])]i=0..m ]

getmaxfd: <fdtable> <int>

getmaxfd(T) =

ConditionValue
T = _ interrorval()
T _d where d:<int> [exists(T, d) k:<int> [exists(T, k) k d]]

(3) SEMANTICS

ACCESS-PROGRAMS

Legality(CREATE((fdt, T), c, K)) =

ConditionValue
K < 0 K global::G_filetable_size()%illegal argument%
0 K K < global::G_filetable_size() isfull(T)%no more free positions%
0 K K < global::G_filetable_size() ¬isfull(T)%legal%

CREATE((fdt, T) , c, K) =

ConditionValue
! m1,m2,n:<int>; e[0]..e[m2]:<int>; k[0]..k[n]:<int>; d0:<int> (m2 m1 m1 0 n 1 0 e[0] i:<int> (0 i i < m2) [e[i] < e[i + 1]] i:<int> (0 i i n) [k[i] 0]) [d0 = getminfree(T) T = [CREATE(*, *1, k[i])]i=0..d0 - 1.CREATE(*, *1, k[d0]).[CREATE(*, *1, k[i])]i=d0 + 1..n.[RELEASE(*, e[i])]i=0..m1 - 1.RELEASE(*, d0).[RELEASE(*, e[i])]i=m1 + 1..m2 ][CREATE(*, *1, k[i])]i=0..d0 - 1.CREATE(*, *1, K).[CREATE(*, *1, k[i])]i=d0 + 1..n.[RELEASE(*, e[i])]i=0..m1 - 1.[RELEASE(*, e[i])]i=m1 + 1..m2
! m,n:<int>; e[0]..e[m]:<int>; k[0]..k[n]:<int>; d0:<int> (-1 m m n 0 e[0] i:<int> (0 i i < m) [e[i] < e[i + 1]] i:<int> (0 i i n) [k[i] 0]) [d0 = getminfree(T) i:<int> (0 i i m) [d0 e[i]] T = [CREATE(*, *1, k[i])]i=0..n.[RELEASE(*, e[i])]i=0..m ][CREATE(*, *1, k[i])]i=0..n.CREATE(*, *1, K).[RELEASE(*, e[i])]i=0..m

CREATE((fdt, T), c , K) = getminfree(T)

Legality(RELEASE((fdt, T), d)) =

ConditionValue
d < 0 d global::G_fdtable_size()%illegal argument%
0 d d < global::G_fdtable_size() ¬exists(T, d)%referenced file descriptor table position doesn't exist%
exists(T, d)%legal%

RELEASE((fdt, T) , d) =

ConditionValue
n = d [CREATE(*, *1, k[i])]i=0..n - h - 1.[RELEASE(*, e[i])]i=0..m - h where h:<int> [ i:<int> (1 i i h) [n - i = e[m - i + 1] (n - h - 1 e[m - h] h = m + 1 )]]
n d[CREATE(*, *1, k[i])]i=0..d - 1.CREATE(*, *1, 0).[CREATE(*, *1, k[i])]i=d + 1..n.[RELEASE(*, e[i])]i=0..m1.RELEASE(*, d).[RELEASE(*, e[i])]i=m1 + 1..m where m1:<int> [e[m1] < d d < e[m1 + 1] e[-1] = -1 e[m + 1] = n ]
where m,n:<int>; e[-1]..e[m + 1]:<int>; k[0]..k[n]:<int> (-1 m m < n 0 e[0] i:<int> (0 i i < m) [e[i] < e[i + 1]] i:<int> (0 i i n) [k[i] 0]) [T = [CREATE(*, *1, k[i])]i=0..n.[RELEASE(*, e[i])]i=0..m ]

Legality(DUP((fdt, T), d)) =

ConditionValue
d < 0 d global::G_fdtable_size()%illegal argument%
0 d d < global::G_fdtable_size() ¬exists(T, d)%referenced file descriptor table position doesn't exist%
exists(T, d) isfull(T)%no more free positions%
exists(T, d) ¬isfull(T)%legal%

DUP((fdt, T) , d) = CREATE((*1,T) , *1, getfiletableindex(T, d))

DUP((fdt, T), d) = getminfree(T)

Legality(EXISTS(T, d)) = %legal%

EXISTS(T, d) = exists(T, d)

Legality(GETMINFREE(T)) = %legal%

GETMINFREE(T) = getminfree(T)

Legality(GETFILETABLEINDEX(T, d)) = %legal%

GETFILETABLEINDEX(T, d) = getfiletableindex(T, d)

Legality(GETMAXFD(T)) = %legal%

GETMAXFD(T) = getmaxfd(T)

Legality(ISFULL(T)) = %legal%

ISFULL(T) = isfull(T)

(4) PROOF SECTION

HYPOTHESIS

k:<int> (0 k k < global::G_filetable_size()) [CREATE((*1,_), *2 , k) = 0 ]

k1,k2:<int> (0 k1 k1 < global::G_filetable_size() (0 k2 k2 < global::G_filetable_size())) [CREATE((*1,CREATE((*1,_) , *3, k1)), *2 , k2) = 1 ]

k1,k2:<int> (0 k1 k1 < global::G_filetable_size() (0 k2 k2 < global::G_filetable_size())) [CREATE((*1,CREATE(*, *3, k1)), *2 , k2) = 1 ]

n,k,j:<int>; c[0]..c[n]:<int>; T:<fdtable> (0 k k n 0 j j n j k s:<int> (0 s s n) [0 c[s] c[s] < global::G_filetable_size()]) [T = [CREATE(*, *1, c[i])]i=0..n.RELEASE(*, k) DUP((*1,T), j) = k ]

T:<fdtable>; fd,new_fd:<int> (EXISTS(T, fd) ) [DUP((*1,T), fd) = new_fd GETFILETABLEINDEX(T, fd) = GETFILETABLEINDEX(T, new_fd) ]