PIONEチュートリアル-PNML

提供: Eospedia
2014年11月5日 (水) 08:00時点におけるKinoshita (トーク | 投稿記録)による版

移動: 案内検索

PIONEは、直接、pione定義書を記述する事もできますが、PNMLを用いて、ペトリネットの形式で記述することもできます. WoPeD(推奨)により、ペトリネットを記述し、PNML形式で保存します。それぞれのアクションは、マークダウン形式で記述する事ができます.

WoPeDを使ったpione定義書の作成

 ここではWoPeDを使って、PNMLファイルを作成し、pione定義書を作成するチュートリアルを行います。

まず、WoPeDを起動し、新規作成するためにFileのNewを選択します。
新規作成したファイル内のProcess上で右クリックすると、アイテムを選択することができます。

PIONE-PNML-WoPeD1.png

pione定義書を作成する上では上部2つの"○"(Place)と"□"(Transition)を使用します。主に"○"(Place)はファイルなどの入出力データを指し、"□"(Transition)はRuleなどの処理を指します。そして、"○"(Place)と"□"(Transition)の間をドラッグ操作による矢印(Annotation)でつなぐと、入力ファイルからある処理を経て出力ファイルを作成するフローが完成します。
PIONE-PNML-WoPeD2.png

WoPeDでフローを作成したら、次は"□"(Transition)の中身を作成します。こちらは下記のようなマークダウン形式ファイルを作成します。##が意味持っていることに注意して下さい。

## Transition名

ここにコメントを記述することができます。

```
Transition内のAction
```

## 次のTransition名
.
.
.


PNMLファイルとマークダウンファイルを作成した後は下記のコマンドによって、pione定義書へコンパイルすることができます。

$ pione compile (pnmlファイル) --action (アクション定義ファイル) > (pione定義書ファイル名)


基本1(特定のファイルを出力する)

 では、PIONEチュートリアル#基本1(特定のファイルを出力する)と同様にHelloプログラムを作ってみましょう。

まず、下記のようなHelloWorld.pnmlを作成します。このとき出力ファイルの">"はMain Ruleにおける出力を指しています。("<"はMain Ruleの入力)
PIONE-PNML-Basic1.png

次に下記のようなHelloWorld.mdを作成します。

# HelloWorld.pione

## Hello
Here, you can write Comment.


```
echo "Hello PIONE world !" > {$O[1]}
```

このファイルはこちらからダウンロードできます。

最後にコンパイルを行います。

pione compile HelloWorld.pnml --action HelloWorld.md > HelloWorld.pione


コンパイル後のpione定義書


Rule Main
  output 'message.txt'
Flow
  rule Hello
End

Rule Hello
  output 'message.txt'
Action
  echo "Hello PIONE world !" > {$O[1]}
End


PIONEチュートリアル#基本1(特定のファイルを出力する)と同様の機能を持つファイルHelloWorld.pioneが作成されました。

実行結果

/Basic1$ pione-client HelloWorld.pione -b HelloWorld
  ==> &Anonymous:Root([],{})
    --> Rule Application: &Anonymous:Root([],{})
      --> Distribution: &Anonymous:Root([],{})
            >>> &Anonymous:Main([],{})
  ==> &Anonymous:Main([],{})
    --> Rule Application: &Anonymous:Main([],{})
      --> Distribution: &Anonymous:Main([],{})
            >>> &Anonymous:Hello([],{})
  ==> &Anonymous:Hello([],{})
   SH ------------------------------------------------------------
   SH echo "Hello PIONE world !" > message.txt
   SH ------------------------------------------------------------
  <== &Anonymous:Hello([],{})
      <-- Distribution: &Anonymous:Main([],{})
    <-- Rule Application: &Anonymous:Main([],{})
      <-- Distribution: &Anonymous:Root([],{})
  <== &Anonymous:Main([],{})
    <-- Rule Application: &Anonymous:Root([],{})
  <== &Anonymous:Root([],{})
/Basic1$ cat HelloWorld/output/message.txt 
Hello PIONE world !

同様にHelloWorld/output/message.txt へHello PIONE world !が出力されています。

基本2(複数ルールによる処理)

 少しルールを増やした例を試してみましょう。
今回は各行に1つずつの数値が記述されている全ての.inファイルに対して、各数に2を掛ける処理(First)、さらに1を足す処理(Second)を施して、.outを出力するルールを作成します。

PNMLファイル
PIONE-PNML-Basic2.png
上記の2つ目のplaceでの{S*}はPIONEの記述における{$I[1]}を表しています。

マークダウンファイル

# Serial2.pione

## First
Multiply 2 to all input data.

```
awk '{print $1*2}' {$I[1]} > {$O[1]}
```

## Second
Add 1 to all input data.

```
awk '{print $1+1}' {$I[1]} > {$O[1]}
```

このファイルはこちらからダウンロードできます。

コンパイル後のpione定義書

Rule Main
  input '*.in'
  output '*.out'
Flow
  rule First
  rule Second
End

Rule First
  input '*.in'
  output '{$*}.route'
Action
  awk '{print $1*2}' {$I[1]} > {$O[1]}
End

Rule Second
  input '*.route'
  output '{$*}.out'
Action
  awk '{print $1+1}' {$I[1]} > {$O[1]}
End


PIONEの実行結果
入力ファイル

test1.in test2.in test3.in test4.in test5.in
3
5

2
4

7
1

8
9
6

1
2
3
4
5
6
7
8
9


出力ファイル

test1.out test2.out test3.out test4.out test5.out
7
11
5
9
15
3
17
19
13
3
5
7
9
11
13
15
17
19

入力ファイルの各データが×2の後に+1の処理が施され、PIONEチュートリアル#基本5(直列:フロールールの設定 )と同様の処理を作成することができました。

基本3(複数種類の入出力がある処理)

 複数種類の入出力がある少し複雑な処理を記述してみましょう。
今回は.txtファイルを元に.swapファイルで指定した行数を入れ替えたファイル.swtxtと.sedファイルで指定した文字列の置換を行ったファイル.sdtxtをそれぞれ出力します。

PNMLファイル
PIONE-PNML-Basic3.png

マークダウンファイル

# TextSwapSed.pione

## TextSwap

```
cp {$I[1]} intmp;
while read line ; \
do \
	i1=$(echo $line | awk '{printf("%d", $1)}'); \
	i2=$(echo $line | awk '{printf("%d", $2)}'); \
	lnum=$(wc -l intmp | awk '{printf("%d", $1)}'); \
	c1=$(expr $lnum - $i2); \
	c2=$(expr $i2 - $i1); \
	top=$( head -$i1 intmp ); \
	middle=$( head -$i2 intmp | tail -$c2 ); \
	bottom=$( tail -$c1 intmp ); \
	t1=$(expr $i1 - 1); \
	m1=$(expr $c2 - 1); \
	top1=$( echo "$top" | head -$t1 ); \
	str1=$( echo "$top" | tail -1 ); \
	middle1=$( echo "$middle" | head -$m1 ); \
	str2=$( echo "$middle" | tail -1 ); \
	echo "$top1" > outtmp; \
	echo "$str2" >> outtmp; \
	echo "$middle1" >> outtmp; \
	echo "$str1" >> outtmp; \
	echo "$bottom" >> outtmp; \
	cat outtmp | sed '/^$/d' > intmp; \
done < {$I[2]};
mv intmp {$O[1]};
```

## TextSed

```
cp {$I[1]} intmp;
while read line ; \
do \
	str1=$(echo $line | awk '{printf("%s", $1)}'); \
	str2=$(echo $line | awk '{printf("%s", $2)}'); \
	sed -e "s/$str1/$str2/g" intmp > outtmp; \
	cat outtmp | sed '/^$/d' > intmp; \
done < {$I[2]};
mv intmp {$O[1]};
```

このファイルはこちらからダウンロードできます。