此文檔旨在使用對象OCL語言的建模者。使用或擴展OCL語言的語言工程師的詳細文檔位於此處。我們建議語言工程師在閱讀詳細文檔之前閱讀此文檔。
ocl Bookshop {
context Shop s inv CustomerPaysBeforeNewOrder: // invariant
forall Customer c in s.customers: // quantifiers available
c.allowedToOrder implies !exists Invoice i in s.invoices:
i.buyer == c && i.moneyPayed < i.invoiceAmount ;
// Method specification for selling a book
context Invoice Stock.sellBook(String iban, int discountPercent, Customer c)
let availableBooks = // set comprehension
{ book | Book book in booksInStock, book.iban == iban }
pre: !availableBooks.isEmpty && // precondition
c.allowedToOrder;
post: let discount = (100 - discountPercent)/100; // postcondition, let
b = result.soldBook // result variable
in
!(b isin booksInStock) &&
booksInStock.size@pre == booksInStock.size + 1 && // @pre
result.invoiceAmount == b.price * discount;
}
進一步的表達示例(包括Monticore的CommoneXpressions):
a + 3*4; // number expressions
a >= b; a < 3; a == "myName"; // equalities
b implies (c && a) || d; // boolean expressions
forall a in S: foo(a) > 3; // quantifiers
exists a in S: foo(a) > 3;
a ?== b; c ?<= d // elvis operators (dealing with optionals)
S.first; S.size; S.addAll(T); // 30 operators for Lists
a in S; S.add(a); // + more for Sets
max(S) > 3; // + more for numbers
文本OCL表示主要取決於[Rum16,Rum17]中的定義。 OCL用於檢查其他模型的正確性。在這裡, Book
和Customer
類型是由類圖定義的:
classdiagram Bookshop {
class Book {
String name;
String iban;
double cost;
double price;
}
class Shop;
association [1] Shop -> (invoices) Invoice [*];
association [1] Shop -> (customers) Customer [*];
class Stock {
void addBook(Book b);
Invoice sellBook(Book bookToSell, int discountPercent, Customer buyer);
}
association [1] Stock -> (booksInStock) Book [*];
class Customer {
String name;
String phoneNumber;
int customerNumber;
boolean allowedToOrder;
void payInvoice(double moneyWired, Invoice invoice);
}
class Invoice {
int invoiceNumber;
double invoiceAmount;
double moneyPayed;
}
association [1] Invoice <-> (buyer) Customer [1];
association [1] Invoice <-> (soldBook) Book [1];
}
本節介紹了OCL語言的命令行工具。該工具提供處理模型時使用的典型功能。為此,它為
OCL工具的構建和使用要求是(至少)JDK 8(JDK 11和JDK 14也得到了我們的正式支持),Git和Gradle已安裝並可用於BASH。如果您使用的是Docker,也可以在不安裝Java,Git或Gradle的情況下使用Docker容器。
以下小節描述瞭如何下載工具。然後,本文檔描述瞭如何從源文件構建工具。之後,本文檔包含用於使用該工具的教程。
準備使用該工具的版本可以以可執行的JAR文件的形式下載。您可以使用此下載鏈接下載該工具。
另外,您可以使用wget
下載該工具。以下命令下載了該工具的最新版本,並以您的工作目錄中的名稱MCOCL.jar
保存:
wget "monticore.de/download/MCOCL.jar" -O MCOCL.jar
可以使用工具的Docker映像的最新版本
docker pull monticore/ocl
如果您使用Docker,請在以下內容中替換java -jar MCOCL.jar
(對於Windows PowerShell,Mac終端或Linux Bash)
docker run --rm -v ${PWD}:/input -w /input monticore/ocl
或(對於Windows命令行)
docker run --rm -v %CD%:/input -w /input monticore/ocl
例如,此教程步驟2的命令
java -jar MCOCL.jar -i Example.ocl -pp
變成
docker run --rm -v ${PWD}:/input -w /input monticore/ocl -i Example.ocl -pp
使用Docker時。
可以從GitHub中的源文件構建一個可執行的工具罐。以下描述了使用bash從源文件構建工具的過程。對於Github中可用源文件的bash的可執行罐子,請執行以下命令。
首先,克隆存儲庫:
git clone https://github.com/MontiCore/ocl.git
將目錄更改為克隆來源的根目錄:
cd OCL
然後通過運行構建項目(信息:您需要為此安裝Gradle):
gradle build
恭喜!現在,您可以在目錄target/libs
(可通過cd target/libs
訪問)中找到可執行的JAR文件MCOCL.jar
。
前面的部分描述瞭如何獲得可執行的JAR文件(OCL命令行工具)。本節提供了使用OCL工具的教程。以下示例假設您本地命名為MCOCL
工具。如果您從源構建工具或上面使用了wget
命令,那麼您就可以了。如果您手動下載了該工具,則應考慮重命名下載的JAR。
執行JAR文件沒有任何選項,打印
到控制台的工具:
$ java -jar MCOCL.jar
usage: OCLTool
-c,--coco <arg> Checks the CoCos for the input. Optional
arguments are:
-c intra to check only the intra-model CoCos,
-c inter checks also inter-model CoCos,
-c type (default) checks all CoCos.
-cd4c,--cd4code Load symbol kinds from CD4C. Shortcut for loading
CDTypeSymbol as TypeSymbol,
CDMethodSignatureSymbol as FunctionSymbol, and
FieldSymbol as VariableSymbol. Furthermore,
warnings about not deserializing
CDAssociationSymbol and CDRoleSymbol will be
ignored.
-d,--dev Specifies whether developer level logging should
be used (default is false)
-fs,--functionSymbol <fqns> Takes the fully qualified name of one or more
symbol kind(s) that should be treated as
FunctionSymbol when deserializing symbol files.
Multiple symbol kinds should be separated by
spaces.
-h,--help Prints this help dialog
-i,--input <files> Processes the list of OCL input artifacts.
Argument list is space separated. CoCos are not
checked automatically (see -c).
-is,--ignoreSymKind <fqns> Takes the fully qualified name of one or more
symbol kind(s) for which no warnings about not
being able to deserialize them shall be printed.
Allows cleaner outputs. Multiple symbol kinds
should be separated by spaces.
-p,--path <directory> Sets the artifact path for imported symbols.
Directory will be searched recursively for files
with the ending ".*sym" (for example ".cdsym" or
".sym"). Defaults to the current folder.
-pp,--prettyprint <files> Prints the OCL model to stdout or the specified
file(s) (optional). Multiple files should be
separated by spaces and will be used in the same
order in which the input files (-i option) are
provided.
-s,--symboltable <files> Stores the symbol tables of the input OCL
artifacts in the specified files. For each input
OCL artifact (-i option) please provide one
output symbol file (using same order in which the
input artifacts are provided) to store its
symbols in. For example, -i x.ocl y.ocl -s
a.oclsym b.oclsym will store the symbols of x.ocl
to a.oclsym and the symbols of y.ocl to b.oclsym.
Arguments are separated by spaces. If no
arguments are given, output is stored to
'target/symbols/{packageName}/{artifactName}.ocls
ym'.
-ts,--typeSymbol <fqns> Takes the fully qualified name of one or more
symbol kind(s) that should be treated as
TypeSymbol when deserializing symbol files.
Multiple symbol kinds should be separated by
spaces.
-vs,--variableSymbol <fqns> Takes the fully qualified name of one or more
symbol kind(s) that should be treated as
VariableSymbol when deserializing symbol files.
Multiple symbol kinds should be separated by
spaces.
為了正常工作,該工具需要強制性參數-i,--input <file>
,該文件將至少一個包含SD模型的輸入文件的文件路徑。如果未指定其他參數,則該工具僅解析模型。
為了嘗試此操作,請將MCOCL.jar
複製到您選擇的目錄中。之後,創建包含以下簡單的OCL:
ocl Example {
}
將文本文件作為Example.ocl
保存在MCOCL.jar
所在的目錄中。
現在執行以下命令:
java -jar MCOCL.jar -i Example.ocl
您可能會注意到該工具不會打印到控制台的輸出。這意味著該工具已成功地解析了文件Example.ocl
。
該工具為OCL語言提供了相當局限性。可以使用一個相當通用的,例如,修復包含OCL的文件的格式。要執行漂亮的打印機-pp,--prettyprint
選項。使用該選項而沒有任何參數,可以很好地打印到控制台輸入文件中包含的模型。
執行以下命令嘗試此操作:
java -jar MCOCL.jar -i Example.ocl -pp
該命令打印到控制台輸入文件中包含的漂亮印刷模型:
ocl Example {
}
可以很好地打印輸入文件中包含的模型到輸出文件。對於此任務,可以將輸出文件的名稱作為參數為-pp,--prettyprint
選項。如果提供了輸出文件的參數,則輸出文件的數量必須等於輸入文件的數量。第i-th輸入文件非常印刷到第i-thupt ofupt文件中。
執行以下命令嘗試此操作:
java -jar MCOCL.jar -i Example.ocl -pp Output.ocl
該命令將輸入文件中包含的精美印刷模型打印到文件Output.ocl
中。
對於檢查上下文條件,可以使用-c,--coco <arg>
選項。使用此選項無任何參數檢查模型是否滿足所有上下文條件。
如果您只想檢查一個模型是否僅滿足上下文條件的子集還是想闡明應檢查所有上下文條件,則可以通過提供三個參數intra
, inter
和type
來做到這一點。
intra
僅執行上下文條件,涉及違反模型內部上下文條件的行為。例如,這些上下文條件,例如檢查命名約定。inter
執行所有模型內部上下文條件,並檢查是否定義了構造函數簽名中的類型名稱。type
執行所有上下文結合。這些上下文條件包括檢查是否存在使用過的類型和方法。使用參數type
時的行為與不使用參數時的默認行為相等。執行以下命令嘗試一個簡單的示例:
java -jar MCOCL.jar -i Example.ocl -c -cd4c
您可能會注意到該工具在執行此命令時沒有打印到控制台。這意味著該模型滿足所有上下文條件。
現在讓我們考慮一個更複雜的例子。從上面的An Example Model
部分中回顧OCL Bookshop
。要繼續,請複制OCL Bookshop
的文本MCOCL.jar
Bookshop.ocl
中。為此,您需要一個包含與Bookshop.ocl
相對應的類圖的符號的符號文件。這將在下一節中進行詳細說明。目前,只需將-p src/test/resources/docs/Bookshop/ -cd4c
添加到命令中,以便使用該工具在哪裡找到為此示例準備的符號文件以及如何處理它。
您可以使用-c,--coco <arg>
選項檢查不同種類的上下文條件:
java -jar MCOCL.jar -i Bookshop.ocl -p src/test/resources/docs/Bookshop/ -cd4c -c intra
java -jar MCOCL.jar -i Bookshop.ocl -p src/test/resources/docs/Bookshop/ -cd4c -c inter
java -jar MCOCL.jar -i Bookshop.ocl -p src/test/resources/docs/Bookshop/ -cd4c -c type
這些命令都不應產生輸出。
要查看錯誤,請讓模型添加一個錯誤。在Bookshop.ocl
中替換此行
{ book | Book book in booksInStock, book.iban == iban }
經過
{ book2 | Book book in booksInStock, book.iban == iban }
由於book2
不確定,該工具現在應在檢查COCO時打印出錯誤消息:
$ java -jar MCOCL.jar -i Bookshop.ocl -p src/test/resources/docs/Bookshop/ -cd4c -c
[INFO] DeriveSymTypeOfExpression package suspected
[ERROR] 0xA0309 Bookshop.ocl:<13,12> Could not calculate type of expression "book2" on the left side of SetComprehension
請記住要撤消“錯誤”。
在本節中,我們利用符號路徑,並為工具提供另一個模型的符號文件(存儲的符號表),其中包含必要的類型信息。
在工具MCOCL.jar
所在的目錄中創建一個新的目錄mytypes
。例如,第一個部分中的Bookshop.ocl
示例需要一個指定其數據類型的類圖。您可以在SRC/TEST/RESOSDES/DOCS/BOOKSHOP/BOOKSHOP.CD下找到此類圖文件。
要在OCL中使用它,您首先需要將其轉換為一個符號文件。類圖的符號文件Bookshop.sym
提供了所有必要的類型信息,以在OCL中使用其類型。如果您此時不想參與CD工具,則還可以在SRC/TEST/Resources/doc/docs/bookshop/bookshop.sym下找到現成的文件。只需將其複製到您的mytypes
文件夾中即可。否則,要將類圖轉換為符號文件,您需要使用CD4Analiss項目中的MCCD.jar
,並使用以下命令轉換類圖文件:
java -jar MCCD.jar -d false --fieldfromrole navigable -i src/test/resources/docs/Bookshop/Bookshop.cd -s mytypes/Bookshop.sym
作為語言用戶,符號文件的內容對您而言至關重要。如果您很好奇並且會查看符號文件:符號文件包含模型中定義的符號的JSON表示。在這種情況下,符號文件包含有關定義類型的信息。通常,Monticore語言的工具會自動生成這些文件的內容,而作為語言用戶,您不必關心其內容。
包含包含符號文件的目錄結構的路徑稱為“符號路徑”。如果我們提供工具的符號路徑,它將在符號文件中搜索符號,這些符號存儲在符號路徑中的目錄中。因此,如果我們希望該工具找到我們的符號文件,則必須通過--path <directory>
選項提供該工具的模型路徑。您可以使用剛創建的mytypes
文件夾嘗試一下:
java -jar MCOCL.jar -i Bookshop.ocl --path <SYMBOLPATH> -c type -cd4c
其中<SYMBOLPATH>
是存儲下載的符號文件的路徑。在我們的示例中,如果您將模型存儲在目錄mytypes
中,請執行以下命令:
java -jar MCOCL.jar -i Bookshop.ocl --path mytypes -c type -cd4c
請注意,此命令還使用-cd4c
標誌。要解釋提供給OCL工具的Symbolfiles,它需要了解如何解釋CD工具存儲的符號。 -cd4c
標誌是用於CD4CODE這樣做的速記。您也可以使用--typeSymbol
, --functionSymbol
和--variableSymbol
標誌手動進行操作,然後是符號類型,應將其解釋為TypeSymbol
, FunctionSymbol
和VariableSymbol
:
java -jar MCOCL.jar -i Bookshop.ocl --path mytypes -c type --typeSymbol <TYPE_SYMBOL_KINDS> --variableSymbol <VAR_SYMBOL_KINDS> --functionSymbol <FUNC_SYMBOL_KINDS>
其中<TYPE_SYMBOL_KINDS>
, <VAR_SYMBOL_KINDS>
和<FUNC_SYMBOL_KINDS>
是符號的完全合格名稱。如果您想提供多種符號類型,只需將它們添加到一個空間分開即可。在我們的示例中,宣布CD4分析的符號看起來像這樣:
java -jar MCOCL.jar -i Bookshop.ocl --path mytypes -c type --typeSymbol de.monticore.cdbasis._symboltable.CDTypeSymbol --variableSymbol de.monticore.symbols.oosymbols._symboltable.FieldSymbol --functionSymbol de.monticore.cd4codebasis._symboltable.CDMethodSignatureSymbol
請注意,該工具現在在無法解釋的符號上發出許多警告。在OCL中,並非每個不同語言的符號都可能很有趣。為了抑制這些意外的警告,您可以使用--ignoreSymKind <SYM_KINDS_TO_IGNORE>
optain>“ option”來告訴您不想收到哪種符號類型的OCL工具。在我們的示例中,這看起來像這樣:
java -jar MCOCL.jar -i Bookshop.ocl --path mytypes -c type --typeSymbol de.monticore.cdbasis._symboltable.CDTypeSymbol --variableSymbol de.monticore.symbols.oosymbols._symboltable.FieldSymbol --functionSymbol de.monticore.cd4codebasis._symboltable.CDMethodSignatureSymbol --ignoreSymKind de.monticore.cdassociation._symboltable.CDAssociationSymbol de.monticore.cdassociation._symboltable.CDRoleSymbol
對於日常使用,這有點複雜。因此請記住, -cd4c
標誌可以將其簡化為
java -jar MCOCL.jar -i Bookshop.ocl --path mytypes -c type -cd4c
上一節描述瞭如何從現有符號文件中加載符號。現在,我們將使用該工具為Bookshop.ocl
型號存儲一個符號文件。存儲的符號文件將包含有關OCL文件中定義的對象的信息。其他模型可以將其導入使用這些對象定義引入的符號,類似於我們更改文件Bookshop.ocl
的方式,用於導入符號文件Bookshop.sym
中包含的符號。
使用-s,-symboltable <file>
選項構建輸入模型的符號表,並將它們存儲在給出的文件路徑中。要么不提供任何文件路徑,要么必須為每個輸入模型提供一個文件路徑。第i-th輸入模型的符號文件存儲在第i-th文件路徑定義的文件中。如果您不提供任何文件路徑,則該工具將每個輸入模型的符號表存儲在“符號文件” target/symbols/{packageName}/{fileName}.oclsym
中,其中packageName
是包含文件中指定的包裝的名稱模型和fileName
是包含模型的文件的名稱。該文件是相對於工作目錄的存儲,即,您執行存儲符號文件的命令的目錄。此外,請注意,為了正確存儲符號,必須在所有方面都對模型進行良好的形式,因此,請事先檢查所有上下文條件。
對於存儲Bookshop.ocl
的符號文件,請執行以下命令(隱式上下文條件檢查需要使用符號路徑選項):
java -jar MCOCL.jar -i Bookshop.ocl --path mytypes -cd4c -s
該工俱生成文件target/symbols/docs/Bookshop.oclsym
,現在可以通過其他模型導入的模型,這些模型需要使用OCL文件Bookshop
中定義的某些對象。
例如,在文件syms/Bookshop.oclsym
中存儲Bookshop.ocl
的符號文件,例如,執行以下命令(再次,隱式上下文條件檢查需要使用符號路徑選項):
java -jar MCOCL.jar -i Bookshop.ocl -path mytypes -cd4c -s syms/Bookshop.oclsym
恭喜,您剛剛完成了有關保存SD符號文件的教程!