<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <style> c1{ color: blue; } c2{ color: red; } </style> <title>【SimpleTwitter(Alloy)】</title> </head> <body> <h1 class="title"> 【SimpleTwitter(Alloy) の課題】 </h1> <p> ここでは,SimpleTwitter の Alloy による仕様記述に関する課題に取り組んでいただきます.<br> 以下に Alloy で記述された SimpleTwitter のモデルを示します.こちらを適宜参照しながらモデルの理解を行ってください. </p> <hr/> <h2>SimpleTwitter の Alloy による仕様記述についての説明</h2> <h3><code><c1>sig</c1></code>:</h3> <p> Alloy では,アカウントidの集合を <code>AccountId</code> ,アカウント名の集合を <code>Name</code> , ツイートの集合を <code>Tweet</code> ,アカウント全体の集合を <code>Accounts</code> ,アカウントの集合を <code>Account</code>,リストの集合を <code>List</code> で表します.<br> 以下のモデルでは <code><c1>sig</c1></code> を用いて,<code>AccountId</code> ,<code>Name</code> ,<code>Tweet</code> ,<code>Accounts</code>,<code>Account</code>,<code>List</code> の順番にこれらの集合を宣言しています.<br> <code>Accounts</code> には,<code>AccountId</code> から <code>Account</code> への対応関係が<code>accountDB</code> フィールドとして定義されています.<br> <code>Account</code> の宣言では,アカウント名を表す <code>name</code> が <code>Name</code> のインスタンスとして, ツイートリストを表す <code>tweets</code> が <code>List</code> のインスタンスとして定義されています.<br> <!--<code>List</code> では,<code>size</code> が <code>Int</code> のインスタンスとして, <c1><code>Int</code></c1> から <code>Tweet</code> への対応関係が <code>element</code> フィールドとして定義されています.<br>--> </p> <h3><code><c1>pred</c1></code>:</h3> <p> 最初の述語として記述されている <code>init</code> は,<code>Accounts</code> の インスタンスである <code>acs</code> が初期化されていることを示しています.<br> 次の<code>signUp</code> は,<code>id</code> に対応するアカウントを登録する前の <code>Accounts</code> のインスタンス <code>acs</code> と, 登録した後のインスタンス <code>acs'</code> の関係を述語として定義しています.<br> ここで <code>n</code> はアカウント名を示しています.<br> <code>tweet</code> では<code>id</code> で登録されているアカウントに対してツイートを行った際の操作前の <code>Accounts</code> のインスタンス <code>acs</code> と, 操作後のインスタンス <code>acs'</code> の関係を述語として定義しています.<br> ここで <code>contents</code> はツイートの内容を表しています.<br> 最後の <code>execute</code> では,<code>init</code> ,<code>signUp</code> ,<code>tweet</code> を この順で呼び出す操作を定義しています.<br> <c1><code>run</code></c1> では,<code>execute</code> を呼び出して仮想実行を行います. </p> <div style="padding: 10px; margin-bottom: 10px; border: 1px solid #333333; border-radius: 10px;"> <pre> <c1>sig</c1> AccountId, Name, Tweet { } <c1>sig</c1> Accounts { accountDB: AccountId <c1>lone</c1> -> <c1>lone</c1> Account } <c1>sig</c1> Account { name: Name, tweets: List } <c1>sig</c1> List { size: <c1>Int</c1>, element: <c1>Int</c1> -> <c1>lone</c1> Tweet } <c1>pred</c1> init[acs: Accounts] { <c1>no</c1> acs.accountDB } <c1>pred</c1> signUp[acs, acs': Accounts, id: AccountId, n: Name] { <c1>some</c1> ac: Account | { <c1>no</c1> id2: AccountId | acs.accountDB[id2] = ac acs'.accountDB = acs.accountDB + id -> ac ac.name = n ac.tweets.size = <c2>0</c2> <c1>no</c1> ac.tweets.element } } <c1>pred</c1> tweet[acs, acs': Accounts, id: AccountId, contents: Tweet] { <c1>some</c1> ac': Account | { <c1>no</c1> id2: AccountId | acs.accountDB[id2] = ac' acs'.accountDB = acs.accountDB ++ id -> ac' ac'.name = acs.accountDB[id].name ac'.tweets != acs.accountDB[id].tweets ac'.tweets.size = plus[acs.accountDB[id].tweets.size, <c2>1</c2>] ac'.tweets.element[minus[ac'.tweets.size, <c2>1</c2>]] = contents <c1>all</c1> n: <c1>Int</c1> | n != minus[ac'.tweets.size, <c2>1</c2>] <c1>implies</c1> ac'.tweets.element[n] = acs.accountDB[id].tweets.element[n] } } <c1>pred</c1> execute[] { <c1>some disj</c1> acs, acs', acs'': Accounts, id: AccountId, n: Name, contents: Tweet | { init[acs] signUp[acs, acs', id, n] tweet[acs', acs'', id, contents] } } <c1>run</c1> execute <c1>for</c1> <c2>2</c2> <c1>but</c1> <c2>3</c2> Accounts </pre> </div> <hr/> <h2>モデルの可視化</h2> <p> 先ほどの SimpleTwitter のモデルの構造を,Alloy の可視化ツールを使用して可視化したものを以下の図に示します.<br> </p> <div class="img-center"> <img src="../img/Alloy/Alloy MetaModel Ver SimpleTwitter.png", class ="before-image-size"><br> </div> <p> この図がモデルの実行に依らない,モデルそのものが持つ構造を表していることに注意して下さい.<br> <code>Accounts</code> が,<code>AccountId</code> のインスタンスを <code>Account</code> のインスタンスに対応させる <code>accountDB</code> というフィールドを持っており, <code>Account</code> が <code>Name</code> のインスタンスを参照する <code>name</code> フィールドと,<code>List</code> のインスタンスを参照する <code>tweets</code> フィールドを,<br> <code>List</code> が <code><c1>Int</c1></code> のインスタンスを参照する <code>size</code>フィールドと, <code><c1>Int</c1></code> のインスタンスを <code>element</code> のインスタンスに対応させる <code>Tweet</code> フィールドをもっていることがわかります. </p> <hr/> <h2>SimpleTwitter モデルの仮想実行について</h2> <p> ここでは,SimpleTwitter モデルの仮想実行について説明します.この仮想実行で用いるテストケースは次の通りです.<br> <ol> <li>Accounts に新しいアカウントを登録します.</li> <li>ツイートを行います.</li> </ol> </p> <h3>仮想実行の可視化:</h3> <p> このテストケースはモデル中の <code>execute</code> 述語で実装されています.<br> <code>execute</code> の仮想実行を可視化したものを以下に示します. </p> <div class="img-center"> <img src="../img/Alloy/Alloy Ver SimpleTwitter.png", class ="before-image-size"><br> </div> <p> 左下にある Accounts2($execute_acs) は <code>execute</code> 述語中の変数 <code>acs</code> で参照される <code>Accounts</code> のインスタンスであり,<code>init</code> 述語を満たしているため, まだ何のアカウント(Account)も登録されていない状態になっています.<br> 次に,1番上の段の左にある Accounts1($execute_acs') は変数 <code>acs'</code> で参照されるインスタンスで, <code>acs</code> で参照されるインスタンスに対して,<code>AccountId</code> で参照される <code>Account</code> のインスタンスをツイートリストの要素数が0の状態で登録したインスタンスになっています.<br> Accounts1 の右にある Accounts0($execute_acs'') は少し複雑です.<br> まず,Accounts1 において,<code>AccountId</code> で参照される Account のインスタンスは Account1 です.このインスタンスに対してツイートを行った後の Account のインスタンスは Account0 になります.<br> ここで Account0 のツイートリストの要素数が1に増加していることに注意して下さい.<br> <code>AccountId</code> で参照される <code>Account</code> のインスタンスが Account1 から Account0 に変わるので,<code>Account</code> のインスタンスも Account1 から Account0 に変わります. </p> <hr/> <h2> 課題概要 </h2> <p> 本課題ではまず,上記にて説明を行った SimpleTwitter の仕様に,ある機能を追加した仕様を考えます.<br> その仕様のモデルと,仮想実行を可視化した以下の図を見ていただいた上で,2つの設問にお答えいただきます.<br> 設問にお答えいただく際は,必ず設問1,設問2の順番でご解答下さい.以下の図と同じものが設問のページにも記載されているのでこのまま設問のページに飛んでいただいてもかまいません. </p> <div style="padding: 10px; margin-bottom: 10px; border: 1px solid #333333; border-radius: 10px;"> <pre> <c1>sig</c1> AccountId, Name, Tweet { } <c1>sig</c1> Accounts { accountDB: AccountId <c1>lone</c1> -> <c1>lone</c1> Account } <c1>sig</c1> Account { name: Name, tweets: List } <c1>sig</c1> List { size: <c1>Int</c1>, element: <c1>Int</c1> -> <c1>lone</c1> Tweet } <c1>pred</c1> init[acs: Accounts] { <c1>no</c1> acs.accountDB } <c1>pred</c1> signUp[acs, acs': Accounts, id: AccountId, n: Name] { <c1>some</c1> ac': Account | acs.accountDB[id] = ac' <c1>implies</c1> { <c1>all</c1> id': AccountId | acs'.accountDB[id'] = acs.accountDB[id'] } <c1>else</c1> { <c1>some</c1> ac: Account | { <c1>no</c1> id2: AccountId | acs.accountDB[id2] = ac acs'.accountDB = acs.accountDB + id -> ac ac.name = n ac.tweets.size = <c2>0</c2> <c1>no</c1> ac.tweets.element } } } <c1>pred</c1> tweet[acs, acs': Accounts, id: AccountId, contents: Tweet] { <c1>some</c1> ac': Account | { <c1>no</c1> id2: AccountId | acs.accountDB[id2] = ac' acs'.accountDB = acs.accountDB ++ id -> ac' ac'.name = acs.accountDB[id].name ac'.tweets != acs.accountDB[id].tweets ac'.tweets.size = plus[acs.accountDB[id].tweets.size, <c2>1</c2>] ac'.tweets.element[minus[ac'.tweets.size, <c2>1</c2>]] = contents <c1>all</c1> n: <c1>Int</c1> | n != minus[ac'.tweets.size, <c2>1</c2>] <c1>implies</c1> ac'.tweets.element[n] = acs.accountDB[id].tweets.element[n] } } <c1>pred</c1> execute[] { <c1>some disj</c1> acs, acs', acs'', acs''': Accounts, id: AccountId, <c1>disj</c1> n, n': Name, contents: Tweet | { init[acs] signUp[acs, acs', id, n] signUp[acs', acs'', id, n'] tweet[acs'', acs''', id, contents] } } <c1>run</c1> execute <c1>for</c1> <c2>2</c2> <c1>but</c1> <c2>4</c2> Accounts </pre> </div> <div class="img-center"> <img src="../img/Alloy/Alloy_Ver_InventoryManagementCheckMinus.png", class ="before-image-size"><br> </div> <p> <strong> <a href="https://docs.google.com/forms/d/e/1FAIpQLSf5rIUfHnzsLMLPZ_KWnsukn3HcEGBSLN-BxzRPzqszyrlj8g/viewform?usp=sf_link" target="_blank" rel="noopener noreferrer"> 課題アンケート (別タブが開きます) </a> </strong> <br> <strong> <a href="https://docs.google.com/forms/d/e/1FAIpQLSf8Ex1RPzMRvyUYIRkCjcIY69fI74sNXK-m4rNAoAcR6_dm4g/viewform?usp=sf_link" target="_blank" rel="noopener noreferrer"> 課題終了後の評価アンケート (別タブが開きます) </a> </strong> </p> <hr> <br> <a href="ST_DTRAM.html">【SimpleTwitter(DTRAM)】へ</a> </body> <style> .title{ text-align: center; } .links-manual-A{ display: flex; flex-direction: column; } .img-center{ display: flex; justify-content: center; align-items: center; } .before-image-size{ max-width: 100%; height: auto; } .after-image-size{ max-width: 100%; height: auto; } </style> </html>