Filetable Module Interface Specification

Informal Introduction

File table is a global system table. It contains one entry for each file in a
system. Such entry is identified by its position in a table; it contains i-node
number of the corresponding file and a current position in the file. File reference
count corresponds to the number of times file has been opened (and not yet closed);
file reference count is decremented each time the file is closed and the file table
entry is removed when the reference count is decremented to zero.

(0) CHARACTERISTICS

-type specified: filetable

-features: non-deterministic, non-parameterized

-foreign types: global

(1) SYNTAX

ACCESS-PROGRAMS

Program Name
Arg#1Arg#2Arg#3Arg#4Result Type
CREATEfiletable:VOint:VRint:Vint:V 
SETPOSfiletable:VOint:Vint:V   
INCCOUNTERfiletable:VOint:V     
DECCOUNTERfiletable:VOint:V     
GETINODETABLEINDEXfiletable:Vint:V    int
GETPOSfiletable:Vint:V    int
EXISTSfiletable:Vint:V    bool
ISFULLfiletable:V      bool

(2) CANONICAL TRACES

canonical(T) n:<int>; m[0]..m[n], k[0]..k[n], pos[0]..pos[n], in[0]..in[n], c[0]..c[n]:<int>0 - 1 n n < global::G_filetable_size() 0 k[0] i:<int>0 i i n [0 - 1 m[i] (0 pos[i] pos[i] < global::G_sequence_size() (0 in[i] in[i] < global::G_inodetable_size()) (i < n k[i] < k[i + 1]))] [T = [CREATE(*, (*1,c[i]) k[i], pos[i], in[i]).[INCCOUNTER(*, k[i])]j=0..m[i]]i=0..n ]

AUXILIARY FUNCTIONS

interrorval: <int>

interrorval() = -1

filetablesize: <filetable> <int>

filetablesize(FT) =

ConditionValue
FT = _ 0
! FT1:<filetable>; k,m,pos,in,c:<int>0 k (0 - 1 m 0 pos 0 in) [FT = FT1.CREATE(*, (*1,c) k, pos, in).[INCCOUNTER(*, k)]i=0..m ]k + 1

isfull: <filetable> <bool>

isfull(FT) = count(FT, "CREATE") = global::G_filetable_size()

getcounter: <filetable> × <int> <int>

getcounter(FT, k) =

ConditionValue
k < 0 k global::G_filetable_size()interrorval()
¬ ! FT1,FT2:<filetable>; m,pos,in,c:<int>0 - 1 m 0 pos 0 in [FT = FT1.CREATE(*, (*1,c) k, pos, in).[INCCOUNTER(*, k)]i=0..m.FT2 0 k k < global::G_filetable_size()]0
! FT1,FT2:<filetable>; m,pos,in,c:<int>0 - 1 m 0 pos 0 in [FT = FT1.CREATE(*, (*1,c) k, pos, in).[INCCOUNTER(*, k)]i=0..m.FT2 0 k k < global::G_filetable_size()]m + 2

exists: <filetable> × <int> <bool>

exists(FT, k) = getcounter(FT, k) 1

getpos: <filetable> × <int> <int>

getpos(FT, k) =

ConditionValue
¬exists(FT, k)interrorval()
exists(FT, k)pos where FT1,FT2:<filetable>; m,pos,in,c:<int> [0 - 1 m 0 pos 0 in FT = FT1.CREATE(*, (*1,c) k, pos, in).[INCCOUNTER(*, k)]i=0..m.FT2 ]

getinodetableindex: <filetable> × <int> <int>

getinodetableindex(FT, k) =

ConditionValue
¬exists(FT, k)interrorval()
exists(FT, k)in where FT1,FT2:<filetable>; m,pos,in,c:<int> [0 - 1 m 0 pos 0 in FT = FT1.CREATE(*, (*1,c) k, pos, in).[INCCOUNTER(*, k)]i=0..m.FT2 ]

(3) SEMANTICS

ACCESS-PROGRAMS

Legality(CREATE((n, FT), (k, C), pos, in)) =

ConditionValue
0 pos pos < global::G_sequence_size() (0 in in < global::G_inodetable_size()) ¬isfull(FT)%legal%
¬(0 pos pos < global::G_sequence_size() (0 in in < global::G_inodetable_size())) ¬isfull(FT)%invalid argument%
0 pos pos < global::G_sequence_size() (0 in in < global::G_inodetable_size()) isfull(FT)%no more free positions%

CREATE((n, FT) , (k, C) k0, pos, in) = FT1.CREATE(*, (*1,C) k0, pos, in).FT2 where FT1,FT2:<filetable> [FT = FT1.FT2 canonical(FT1.CREATE(*, (*1,C) k0, pos, in).FT2)]

CREATE((n, FT), (k, C) k0, pos, in) | ¬exists(FT, k0)

Legality(SETPOS((n, FT), k, pos)) =

ConditionValue
k < 0 k global::G_filetable_size() pos < 0 pos global::G_sequence_size()%invalid argument%
0 k k < global::G_filetable_size() (0 pos pos < global::G_sequence_size() ¬exists(FT, k))%referenced file table position doesn't exists%
0 pos pos < global::G_sequence_size() exists(FT, k)%legal%

SETPOS((n, FT) , k, pos) = newFT where FT1,FT2,newFT:<filetable>; m,p,in,c:<int> [0 - 1 m 0 p 0 in (FT = FT1.CREATE(*, (*1,c) k, p, in).[INCCOUNTER(*, k)]i=0..m.FT2 newFT = FT1.CREATE(*, (*1,c) k, pos, in).[INCCOUNTER(*, k)]i=0..m.FT2 )]

Legality(INCCOUNTER((n, FT), k)) =

ConditionValue
k < 0 k global::G_filetable_size()%invalid argument%
0 k k < global::G_filetable_size() ¬exists(FT, k)%referenced file table position doesn't exists%
exists(FT, k)%legal%

INCCOUNTER((n, FT) , k) = newFT where FT1,FT2,newFT:<filetable>; m,pos,in,c:<int> [0 - 1 m 0 pos 0 in (FT = FT1.CREATE(*, (*1,c) k, pos, in).[INCCOUNTER(*, k)]i=0..m.FT2 newFT = FT1.CREATE(*, (*1,c) k, pos, in).[INCCOUNTER(*, k)]i=0..m + 1.FT2 )]

Legality(DECCOUNTER((n, FT), k)) =

ConditionValue
k < 0 k global::G_filetable_size()%invalid argument%
0 k k < global::G_filetable_size() ¬exists(FT, k)%referenced file table position doesn't exists%
exists(FT, k)%legal%

DECCOUNTER((n, FT) , k) =

ConditionValue
! m:<int>m 0 [FT = FT1.CREATE(*, (*1,c) k, pos, in).[INCCOUNTER(*, k)]i=0..m.FT2 ]FT1.CREATE(*, (*1,c) k, pos, in).[INCCOUNTER(*, k)]i=0..m - 1.FT2
FT = FT1.CREATE(*, (*1,c) k, pos, in).FT2 FT1.FT2
where FT1,FT2:<filetable>; pos,in,c:<int> [0 pos 0 in]

Legality(GETINODETABLEINDEX(FT, k)) = %legal%

GETINODETABLEINDEX(FT, k) = getinodetableindex(FT, k)

Legality(GETPOS(FT, k)) = %legal%

GETPOS(FT, k) = getpos(FT, k)

Legality(EXISTS(FT, k)) = %legal%

EXISTS(FT, k) = exists(FT, k)

Legality(ISFULL(FT)) = %legal%

ISFULL(FT) = isfull(FT)