This article describes a small example of how the use of the Alloy modeling language can help in software development.
About the quality of software and tools
Typeable , . :
- Haskell
- -
- , QA
( Octopod QA) - pre-production
, . , .
. , , 30 . CI, 30 . , 30 , CI .
, : QA- , - . , , !
, , ? , , !
Alloy
Alloy. Alloy β , , .
, Alloy . Alloy , . , .
. :
newAuthCode
:: (MonadWhatever m)
=> DB.Client
-> DB.SessionId
-> m DB.AuthorizationCode
newAuthCode clid sid = do
let codeData = mkAuthCodeFor clid sid
void $ DB.deleteAllCodes clid sid
void $ DB.insertAuthCode codeData
return code
HTTP- , , . , . Β« Β» (uniqueness constraint violation).
?
, , Alloy. , . newAuthCode
Alloy. , , , .
, , .
, , . , . Alloy, :
open util/time // Time sig Operation // ... { delete : Time // ... - , insert : Time // ... - } { lt[delete,insert] // lt[first,delete] // // } run {some Operation} for 4 // // <= 4
. , Operation
, .
, alloy . 'execute' 'show', :
Alloy , 'next'.
, ( 'nextβ 'Table'):
ββββββββββββββββ¬βββββββ¬βββββββ βthis/Operationβdeleteβinsertβ ββββββββββββββββΌβββββββΌβββββββ€ βOperationβ° βTimeΒΉ βTimeΒ³ β β Operationβ° TimeΒΉ ββββββββββββββββΌβββββββΌβββββββ€ TimeΒ³ βOperationΒΉ βTimeΒ² βTimeΒ³ β β OperationΒΉ TimeΒ² ββββββββββββββββ΄βββββββ΄βββββββ TimeΒ³ β !
, , , Alloy , !
, : , , . , , postgresql , .
!
!
, .
code <- run $ do
handleJust constraintViolation
(launchPG $ selectCodeForSession clid scope sid
(launchPG . pgWithTransaction $ newAuthCode clid scope sid)
, , , , . , select
, .
?
Alloy , :
open util/time // Time sig Token {} // Token one sig DBState // {userToken : Token lone -> Time} // // (.. ) sig Operation { delete : Time , insert : Time , select : Time // select } { lt[first,delete] // // lt[delete,insert] // delete lte[insert,select] // select insert' no userToken.(insert.prev) // (.. => insert = select // ), // // (.. // 'INSERT RETURNING'). // // , select }
. DBState
, , select, , . , , , .
, . , :
fact Trace { // Trace all t : Time - first | { // , : some delete.t => no userToken.t // , some insert.t => some userToken.t // , no delete.t and no insert.t // , , => userToken.t = userToken.(t.prev) // } }
, .
, , . Alloy . , , , select.
Alloy .
assert selectIsGood { // , all s : Operation.select | // , select, some userToken.s // } check selectIsGood for 6 // , selectIsGood
, :
ββββββββββ¬βββββββββββββ βDBState βuserToken β ββββββββββΌβββββββ¬ββββββ€ βDBStateβ°βTokenΒ²βTimeΒ³β β β βββββββ€ β TokenΒ² TimeΒ³ Timeβ΅ β β βTimeβ΅β β ββββββββΌββββββ€ β βTokenΒ³βTimeΒ²β β TokenΒ³ TimeΒ². ββββββββββ΄βββββββ΄ββββββ β TimeΒ², TimeΒ³ Timeβ΅ , Timeβ΄ ! ββββββββββββββββ¬βββββββ¬βββββββ¬βββββββ βOperation βdeleteβinsertβselectβ ββββββββββββββββΌβββββββΌβββββββΌβββββββ€ βOperationβ° β TIMEβ΄β Timeβ΅β Timeβ΅β ββββββββββββββββΌβββββββΌβββββββΌβββββββ€ βOperationΒΉ β TimeΒΉβ TimeΒ³β TIMEβ΄β β Timeβ΄ ββββββββββββββββΌβββββββΌβββββββΌβββββββ€ select OperationΒΉ! βOperationΒ² β TimeΒΉβ TimeΒ²β TimeΒ²β ββββββββββββββββ΄βββββββ΄βββββββ΄βββββββ β β β ,
. , . -, . , , , . , , select .
, , , , , !
.
, Alloy. , , . , .
, , , , , . , Alloy, «».
, . ? , , , , , .
Alloy?
, , , Alloy:
- https://alloytools.org/ < β
- https://alloy.readthedocs.io/en/latest/ < β
- https://mitpress.mit.edu/books/software-abstractions < β Alloy, . , .
- https://alloytools.org/citations/case-studies.html < β Alloy . .
P.S. , .