PIONEチュートリアル-PNML

提供: Eospedia
2014年11月6日 (木) 07:41時点における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]};
```

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

コンパイル済みpione定義書の実行結果
入力ファイル

aaa
aab
aba
abb
baa
bab
bba
bbb

abc
acb
bac
bca
cab
cba

1 3
4 5
1 6

1 2
1 3
1 4
1 5
1 6

a c
bc bd
dc DC

abc ddd
aaa eee
bc XX

Input1.txt Input2.txt line1.swap line2.swap ref1.sed ref2.sed


出力ファイル

bab
aab
aaa
baa
abb
aba
bba
bbb

bab
aaa
aab
aba
abb
baa
bba
bbb

ccc
ccb
cbd
cbb
bDC
bdb
bbd
bbb

eee
aab
aba
abb
baa
bab
bba
bbb

Input1-line1.swtxt Input1-line2.swtxt Input1-ref1.sdtxt Input1-ref2.sdtxt
cba
acb
abc
cab
bca
bac

cba
abc
acb
bac
bca
cab

cbd
ccb
bDC
bDC
ccb
cbd

ddd
acb
bac
XXa
cab
cba

Input2-line1.swtxt Input2-line2.swtxt Input2-ref1.sdtxt Input2-ref2.sdtxt


それぞれの.txtファイルに付いて.sed, .swapファイルによる変換が行われるので、計8つのファイルが出力されます。