逆指値注文の特許があるとは。
特許第3875206号
それにしても請求項の記述が長いので、文字数を調べてみた。
請求項1:1338文字
請求項2:1647文字
がんばったなぁ。
~ただのメモ置き場。なので、内容の正しさについての保証は一切ありませんよ~ copyright (c) 2006-2024 bluewidz, all rights reserved.
逆指値注文の特許があるとは。
特許第3875206号
それにしても請求項の記述が長いので、文字数を調べてみた。
請求項1:1338文字
請求項2:1647文字
がんばったなぁ。
投稿者 bluewidz 0 コメント
WBSで出ていたが、08年度からリースで借りた設備が資産計上されるのだそうだ。
これじゃあリースのメリットが一つなくなるな。
リース業界も再編らしい。
投稿者 bluewidz 0 コメント
続続続ets module
ets:matchの関連関数を使ってみる。
<ets_tut5.erl>
-module(ets_tut5).
-export([test/0]).
test()->
P = ets:new(test1, [bag]),
ets:insert(P, [{a,1,r},{b,2,s},{b,3,u},{b,4,u},{c,5,u}]),
io:format("~p~n", [ets:match_object(P, {'_','$1','$2'})]),
io:format("~p~n", [ets:match_object(P, {'_','_','_'})]),
io:format("~p~n", [ets:match_object(P, {'_','_','u'})]),
ets:delete(P).
-module(ets_tut6).
-export([test/0]).
test()->
P = ets:new(test1, [bag]),
ets:insert(P, [{a,1,r},{b,2,s},{b,3,u},{b,4,u},{c,5,u}]),
X = foreach(P, {'b','_','_'},
fun(X)->io:format("~p~n", [X]) end),
ets:delete(P),
X.
foreach(P, Pattern, Fun)->
foreach(ets:match_object(P, Pattern, 1), Fun).
foreach(X, _) when X=='$end_of_table' ->ok;
foreach({Match, Cont}, Fun)->
lists:foreach(Fun, Match),
foreach(ets:match_object(Cont), Fun).
投稿者 bluewidz 0 コメント
続続ets module
ets:matchを使ってみる。
この関数はパターンに一致したtupleをテーブルから取り出す。
取り出される値はtupleそのものではなく、指定したtupleの要素のリストとなる。
形式的な定義はリファレンスマニュアルをみればわかるので、使用例を示す。
<ets_tut4.erl>
-module(ets_tut4).
-export([test/0]).
test()->
P = ets:new(test1, [bag]),
ets:insert(P, [{a,1,r},{b,2,s},{b,3,u},{b,4,u},{c,5,u}]),
io:format("~p~n", [ets:match(P, {'_','$1','$2'})]),
io:format("~p~n", [ets:match(P, {'_','$2','$1'})]),
io:format("~p~n", [ets:match(P, {a,'$1','_'})]),
io:format("~p~n", [ets:match(P, {b,'_','$1'})]),
io:format("~p~n", [ets:match(P, {'$1','_',u})]),
ets:delete(P).
投稿者 bluewidz 0 コメント
続ets module
ets:foldlとets:foldr関数を使ってみる。
lists:foldsとlists:foldrと同様だそうだ。
<ets_tut2.erl>
-module(ets_tut2).
-export([test/0]).
fold(Option)->
P = ets:new(test1,Option),
ets:insert(P,{a}),
ets:insert(P,{b}),
ets:insert(P,{c}),
CL = ets:foldl(fun(X, Con)->[X|Con] end, [{d}], P),
io:format("foldl ~p ~p~n", [Option, CL]),
CR = ets:foldr(fun(X, Con)->[X|Con] end, [{d}], P),
io:format("foldr ~p ~p~n", [Option, CR]),
ets:delete(P).
test()->
fold([]),
fold([ordered_set]).
-module(ets_tut3).
-export([test/0]).
test()->
lookup([set]),
lookup([ordered_set]),
lookup([bag]),
lookup([duplicate_bag]).
lookup(Option)->
P = ets:new(test1, Option),
ets:insert(P, [{a,10},{a,20},{a,20},{b,1},{b,5},{b,2}]),
io:format("~p ~p~n", [Option, ets:lookup(P,a)]),
io:format("~p ~p~n", [Option, ets:lookup(P,b)]),
io:format("~p ~p~n", [Option, ets:lookup_element(P,a,2)]),
io:format("~p ~p~n", [Option, ets:lookup_element(P,b,2)]),
ets:delete(P).
投稿者 bluewidz 0 コメント
ets:new とその関連関数を使ってみる。
これらの関数はテーブルを作成して、そこに色々な要素を記録しておくために使われるようだ。
C++のstd::mapの高機能版のようなものか?
まず、テーブルを作成する。
第1引数はテーブルの名前で、第2引数はオプションを指定する。[]でデフォルトが利用される。
Pにはテーブル識別子(マニュアルではtid()と記載されている)が代入される。
1> P=ets:new(table1,[]).
16
次にこのテーブルの情報を見てみる。
2> ets:info(P).
[{memory,279},
{owner,<0.30.0>},
{name,table1},
{size,0},
{node,nonode@nohost},
{named_table,false},
{type,set},
{keypos,1},
{protection,protected}]
マニュアルによるとmemory は 「The number of words allocated to the table.」
とのことなので、単位をbytesであるとはいえそうにない。
sizeはテーブルに記録されているオブジェクトの数で、今は空なので0になっている。
テーブルに要素を追加してみる。
3> ets:insert(P, {aaa}).
true
テーブルの情報をみると、
4> ets:info(P).
[{memory,289},
{owner,<0.30.0>},
{name,table1},
{size,1},
{node,nonode@nohost},
{named_table,false},
{type,set},
{keypos,1},
{protection,protected}]
となっており、要素数が1増えている。
さらに追加してみると、
5> ets:insert(P, {bbb}).
true
6> ets:info(P).
[{memory,299},
{owner,<0.30.0>},
{name,table1},
{size,2},
{node,nonode@nohost},
{named_table,false},
{type,set},
{keypos,1},
{protection,protected}]
要素数が2になった。また、memoryが10ずつ増えている。
もう少し短いatomを追加してみる。
7> ets:insert(P, {c}).
true
8> ets:info(P).
[{memory,309},
{owner,<0.30.0>},
{name,table1},
{size,3},
{node,nonode@nohost},
{named_table,false},
{type,set},
{keypos,1},
{protection,protected}]
要素数が3になり、memoryは前と同様に10増える。
要素を順番に見ていくには、ets:first/1とets:second/2を使う。
まずets:first/1を使って、
9> ets:first(P).
c
最初の要素はcのようだ。次にets:next/2を使って、
cの要素の次に記録されている要素を順次取得する。
10> ets:next(P,c).
aaa
11> ets:next(P,aaa).
bbb
12> ets:next(P,bbb).
'$end_of_table'
テーブルの最後までくると、'$end_of_table'が返される。
これで終端かどうかが判断できる。
ところで、このテーブルの機能は便利なのだが
テーブルに記録した値は変更できてしまうことになる。
使い方によってはC言語っぽい書き方ができてしまいそうだ。
また、ets.erlによると、これらetsモジュールの関数の一部、
例えばnewやfirst, nextの実装はC言語でされているとのことだ。
投稿者 bluewidz 0 コメント
ファイル名に.を含めてみる。
<ets.tut1.erl>
-module(ets.tut1).
-export([test/0]).
test()->io:format("~p~n", ["test"]).
投稿者 bluewidz 0 コメント
●正規表現ライブラリ regexp を使ってみる。
一致した位置を取得する関数 match を使ってみる。
最初の引数が処理対象の文字列で、第2引数が正規表現。
1> regexp:match("a,bc,def,123", ",").
{match,2,1}
結果の2番目が一致した位置で、この場合は最初の,が一致している位置なので、2になる。
0 originではなく、1 originである。
戻り値の最後の値は一致した文字数になので、1になる。
2> regexp:match("a,bc,def,123", ",d").
{match,5,2}
この例では2文字一致しているので戻り値の3番目の値が2になっている。
3> regexp:match("a,bc,def,123", ",d.f").
{match,5,4}
ピリオド.は任意の1文字に一致するので、,defが一致している。
4> regexp:match("a,bc,def,123", ",d.*2").
{match,5,7}
*は0個以上の文字に一致するので、.*で任意の0個以上の文字への一致を調べることになる。
なので、「,def,12」に一致することになり、一致した文字の長さは7文字になる。
マニュアルによるとmatchよりもfirst_matchを使用する方が速いとのこと。
使いかたは同じで、
5> regexp:first_match("a,bc,def,123", ",d.*2").
{match,5,7}
一致する部分を全てみつけたい場合は matches を使う。
6> regexp:matches("a,bc,def,123", ",").
{match,[{2,1},{5,1},{9,1}]}
コンマ,の場所を見付けているので、2文字目、5文字目, 9文字目が見つかる。
今度は、一致した場所の文字を置換する。置換には sub を使う。
この関数では最初に見つけた位置の文字を置き換えるだけ。
7> regexp:sub("a,bc,def,123", ",", " ").
{ok,"a bc,def,123",1}
返される結果の2番目は、置換処理後の文字列となっており、
最初のコンマがスペースに置き換えられている。
一致した場所全てを置き換えたい場合は gsub を使う。
8> regexp:gsub("a,bc,def,123", ",", " ").
{ok,"a bc def 123",3}
結果の3番目の値は置き換えた"箇所"の数で、この例ではコンマが3箇所あるので3になる。
一致した場所で文字列を分割する。これには split を使う。
9> regexp:split("a,bc,def,123", ",").
{ok,["a","bc","def","123"]}
コンマで分割された文字列のリストとして結果が返される。
今回はここまで。
投稿者 bluewidz 0 コメント
●ファイル
ファイルの入出力の方法について調べてみた。
まずは、ファイルからの読み込み。
<tut11.erl>
-module(tut11).
-export([read/1]).
read(FileName)->
Handle = file:open(FileName, read),
if element(1,Handle) /= ok -> element(1, Handle);
true -> show_content(element(2,Handle)),
file:close(element(2, Handle))
end.
show_content(Handle)->
Result = io:get_line(Handle, prompt),
if Result == eof -> ok;
true -> io:format("~p~n",[Result]),
show_content(Handle)
end.
abc
def
123
-module(tut12).
-export([write/2]).
write(FileName, Str)->
Handle = file:open(FileName, write),
if element(1,Handle) /= ok -> element(1, Handle);
true -> write_content(element(2,Handle), Str),
file:close(element(2, Handle))
end.
write_content(_, [])->ok;
write_content(Handle, [Head|Rest])->
io:format(Handle, "~p,~w,~s~n", [[Head],[Head],[Head]]),
write_content(Handle, Rest).
投稿者 bluewidz 0 コメント
●文字列に関して
Atomは文字で、小文字から始まらないorアルファベットか数字以外の文字で
構成されるときはシングルクォート'で囲まないといけない。
Stringはダブルクォート"で囲まれた文字。
Erlangのデータ型ではなく、Listとして表現される。
●Shellに関して
Shellで定義した変数を消去するには、f()を使うとよい。
1> X=1.
1
2> X=2.
=ERROR REPORT==== 2-May-2007::22:19:18 ===
Error in process <0.30.0> with exit value: {{badmatch,2},[{erl_eval,expr,3}]}
** exited: {{badmatch,2},[{erl_eval,expr,3}]} **
3> f().
ok
4> X=2.
2
さらに特定の変数の定義を除去することもできる。
5> Y=3.
3
6> X=3.
=ERROR REPORT==== 2-May-2007::22:20:08 ===
Error in process <0.33.0> with exit value: {{badmatch,3},[{erl_eval,expr,3}]}
** exited: {{badmatch,3},[{erl_eval,expr,3}]} **
7> Y=2.
=ERROR REPORT==== 2-May-2007::22:20:10 ===
Error in process <0.38.0> with exit value: {{badmatch,2},[{erl_eval,expr,3}]}
** exited: {{badmatch,2},[{erl_eval,expr,3}]} **
この時点で、X=3, Y=2となっている。
8> f(Y).
ok
これでYの定義のみが消去された。なので、
9> X=3.
=ERROR REPORT==== 2-May-2007::22:20:18 ===
Error in process <0.40.0> with exit value: {{badmatch,3},[{erl_eval,expr,3}]}
** exited: {{badmatch,3},[{erl_eval,expr,3}]} **
のように、Xは定義済みなので再定義できないが、Yについては先ほど消去しているので
10> Y=2.
2
のように再定義できる。
●erlangプログラムのコンパイル
いろいろ探してみたが、ネイティブコードを出力するコンパイラを見つけられない…
とりあえず、UNIXのshellから実行できるようにするには、
(1)コマンドラインから.erlファイルを実行
(2).erlプログラムの最後にhalt().を書いて、shellを止める
の2つを行うしかなさそうだ。
あんましよさげではないが、例えば
<tut10.erl>
-module(tut10).
-export([main/1]).
main(X)->io:format("~p~n",[X]),
halt().
のようなファイルを作成し、
UNIX> erl -compile tut10.erl
としてコンパイルして、
UNIX> erl -noinput -run tut10 main abc
["abc"]
のようにして実行する。ちなみに日本語を入れると、
UNIX> erl -noinput -run tut10 main あ
[[227,129,130]]
となり、日本語の出力ができない。
データの値からしてUTF-8でエンコードされているようだ。
なので、ファイルにバイナリで出力できれば読めそう。
erlang shell や UNIX shell に日本語を出力する方法は見つけられず…
投稿者 bluewidz 0 コメント
今度は、標準モジュールの説明。
マニュアルはコマンドラインから
# erl -man io
で見ることができる。この場合は、ioモジュールのマニュアルが表示される。
これはerlangのシェルからではなく、csh等の通常のシェルから実行する。
# io:format("test~n").
test
ok
# io:format("test~n", []).
test
ok
引数なしでも空リスト引数でも表示できる。
# io:format("test ~w.~n", [AAA]).
** 1: variable 'AAA' is unbound **
大文字だと文法違反のようだ。
# io:format("test ~w.~n", [aaa]).
test aaa.
ok
小文字ならOK。
# io:format("test ~w.~n", ["AAA"]).
test [65,65,65].
ok
""で囲むと文法違反にはならないが、文字列ではなく数字のリストに変換される。
6> io:format("test ~w.~n", ['AAA']).
test 'AAA'.
ok
''で囲むと望みどおりのAAAが表示される。
# io:format("test 1:~w 2:~w ~~.~n", ['AAA','BBB']).
test 1:'AAA' 2:'BBB' ~.
ok
2つ以上表示させたい場合は、リストの要素を増やせば良い。
フォーマット部分の文字列には~wを2個書く。このへんはC++のboost:formatのようだ。
~を表示させたいときは~~と書けば良い。
次に最小値を求める関数を作成する。
ここでは「guard」というのを使用する。
<tut6.erl>
-module(tut6).
-export([list_min/1]).
list_min([Head|Rest])->list_min(Rest, Head).
list_min([], Result)->Result;
list_min([Head|Rest], Result) when Head < Result ->list_min(Rest, Head);
list_min([Head|Rest], Result)->list_min(Rest, Result).
実行すると、
# c(tut6).
./tut6.erl:6: Warning: variable 'Head' is unused
{ok,tut6}
# tut6:list_min([7,2,5,7,9,1,3]).
1
のようになり、最小値が得られる。「when」というのが関数実行の条件で、
trueの場合に関数の中身が実行される。そうでない場合は、関数の次の定義が実行される。
このように条件をテストすることを「guard」と呼ぶようだ。
guardで使える条件文は <, >, == <=, >=, /=がある。
/=はnot equalであり、C++とは違うので注意。
リストにはもう少し機能がある。| operatorにはリストの先頭に要素を追加する機能がある。
まず、リストを作成する。
# L = ['AAA','BBB'].
['AAA','BBB']
| operatorでリストの先頭に要素を追加する。
# L3 = ['CCC'|L].
['CCC','AAA','BBB']
逆向きに書くと、
# L2 = [L|'CCC'].
[['AAA','BBB']|'CCC']
となり、'CCC'のみ持つリストの先頭に['AAA','BBB']というリストが
追加されることになる。
これを使って、リストの順序を逆にする関数を作ってみる。
<tut8.erl>
-module(tut8).
-export([reverse/1]).
reverse(List)->reverse(List, []).
reverse([Head|Rest], ReversedList)->reverse(Rest, [Head|ReversedList]);
reverse([], ReversedList)->ReversedList.
4行目でHeadから順にReversedListの先頭に追加しているところがミソ。
# c(tut8).
{ok,tut8}
# tut8:reverse([1,2,3,4,5]).
[5,4,3,2,1]
逆順になった。
関数に連続した処理をさせたい場合は、「,」で区切ればよく、
<tut7a.erl>
-module(tut7a).
-export([format/1]).
format(Str)->
io:format("test : ~w~n", [Str]),
io:format("test2 : ~w~n", [Str]).
のように書ける。これを実行すると、
# c(tut7a).
{ok,tut7a}
# tut7a:format(aa).
test : aa
test2 : aa
ok
となり、文字列の出力を2回行うようになる。
今度は与えられた値のリストから最小値と最大値をとってみる。
<tut7b.erl>
-module(tut7b).
-export([minmax/1]).
minmax([Head|Rest])->minmax(Rest, Head, Head).
minmax([Head|Rest], Min, Max)->
if Head < Min -> NewMin = Head;
true -> NewMin = Min
end,
if Head > Max -> NewMax = Head;
true -> NewMax = Max
end,
minmax(Rest, NewMin, NewMax);
minmax([], Min, Max) -> {Min, Max}.
コンパイルして実行してみる。
# c(tut7b).
{ok,tut7b}
# tut7b:minmax([1,2,3,4,5,6,7]).
{1,7}
# tut7b:minmax([5,3,8,0,2,4,5]).
{0,8}
たしかに最小値と最大値がとれている。
条件文ifは上記のように書けばよく、条件の間は;で区切る。
endの直前の条件文には;はいらない。
elseがないので、代わりに一番最後にtrue->とすることで対応する。
もう少しifについて調べてみる。
<tut9.erl>
-module(tut9).
-export([test/2]).
test(X,Y)->
if X==1 -> 'X == 1';
Y==2 -> 'Y == 2';
X==2, Y==5 -> 'X==2, Y==5';
X==3;
Y==4 -> 'X==3 or Y==4';
(X==5) and (Y==5) -> 'X==5 and Y==5'
end.
実行すると、
# c(tut9).
{ok,tut9}
# tut9:test(1,2).
'X == 1'
Xが1なので、一番最初の条件に一致する。
# tut9:test(0,2).
'Y == 2'
Xが1でなく、Yが2なので、2番目の条件に一致する。
# tut9:test(2,5).
'X==2, Y==5'
今度は3番目の条件に一致する。
# tut9:test(3,5).
'X==3 or Y==4'
これは4番目の条件に一致する。
C++でいうswitch-cast文と似ていて、;のみで->がない場合は、
->が見つかったところから実行するようだ。
# tut9:test(5,5).
'X==5 and Y==5'
最後は両方共が5の場合の条件である。
# tut9:test(6,5).
=ERROR REPORT==== 1-May-2007::17:01:33 ===
Error in process <0.44.0> with exit value: {if_clause,[{tut9,test,2},{shell,exprs,6},{shell,eval_loop,3}]}
** exited: {if_clause,[{tut9,test,2},{shell,exprs,6},{shell,eval_loop,3}]} **
条件にマッチしないとこんな風にエラーになる。
ちなみに10行目を
(X==5) and (Y==5)
と書かず、
X==5 and Y==5
と書くとコンパイルエラーになる。
最後に高階関数(higher order functions)について試してみる。
C++でいう関数ポインタみたいなもの。
シェルから使うと、次のようになる。
18> Fn = fun (X)->X*3 end.
#Fun<erl_eval.6.56006484>
19> Fn(5).
15
引数の値を3倍する関数Fnを定義して、その引数に5を入れると15が出力される。
高階関数の定義はfunとendで囲むようだ。
標準モジュールのlistsを使うと、次のようなことができる。
20> lists:map(Fn, [1,2,3]).
[3,6,9]
リスト[1,2,3]の各要素に対してFnを適用し、その結果をリストに入れる操作が行われている。
他にも、
25> Fp = fun (X)->io:format("elm : ~w~n",[X]) end.
#Fun<erl_eval.6.56006484>
26> lists:map(Fp, [1,2,3]).
elm : 1
elm : 2
elm : 3
[ok,ok,ok]
27> lists:foreach(Fp, [1,2,3]).
elm : 1
elm : 2
elm : 3
ok
といったことができる。
ソートも次のようにできる。
30> lists:sort([2,3,1]).
[1,2,3]
31> lists:sort(fun(X,Y)->X<Y end,[2,3,1]).
[1,2,3]
32> lists:sort(fun(X,Y)->X>Y end,[2,3,1]).
[3,2,1]
名前とペアになっている要素からなるリストに対してもソートできる。
33> lists:sort(fun({_,X},{_,Y})->X<Y end,[{'A',2},{'B',3},{'C',1}]).
[{'C',1},{'A',2},{'B',3}]
ここで、「 _ 」はanonymous variableと呼ばれ、使わない値に使用するようだ。
今の例では、文字は比較に使わないので「 _ 」を使って表現を簡略化した。
今回はここまで。
投稿者 bluewidz 0 コメント