Newer
Older
SpecificationSimulatorExperiments / courseA / ST_Alloy.html
okazakitakehiro on 9 Sep 11 KB 半角スペースの修正.
<!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>