戻ってくるアリアドネのために部屋を整える

NHKの笑わない数学の第一弾は「確率論」,第二弾は「非ユークリッド幾何」でどちらもFBの数学グループで話題沸騰中だ.わたしも巻き込まれてだいぶ時間を消費してしまったが,本線に戻ろう.グラフの隣接行列から距離行列を生成する「ワーシャル・フロイド法」というアルゴリズムがあり,これをハミルトン閉路問題に応用するという課題がにわかに浮上してきた.ロバート・フロイドがこのアルゴリズムを最初に発表したのは1962年(それ以前にバーナード・ロイとステファン・ワーシャルが独立に発見している)で,現在の三重ループの形に整理されたのはピーター・インガーマン(1962)による.

このアルゴリズムは元々はオートマトンや正規表現の世界から渡ってきたようで,重み付き最短経路を多項式時間で計算することができ,さらに重みの和が負であるようなサイクルを含まないグラフのサイクル検出にも適用できる.また,推移的閉包の検出にも適用可能であるようだ.FBのコメントではこのアルゴリズムが「フロイド・ライブネッツアルゴリズム」という名称で紹介されていた.

https://pydocument.hatenablog.com/entry/2023/04/29/132317?fbclid=IwAR1gENpzpPoA2siiWajP0Z3eyj4oCE9R4All5ovWCpKaCTFMPa6FebswHrY

しかし,どこを探してもそのようなものは出てこない.そもそも,Leibnizの名前をライブネッツとなまっている時点でおかしいのだが,上の記事では何度もこの名前で出てくるので執筆者はそれが正しいと確信しているようだ.この記事はHatena BlogのPyDocumentというシリーズものの一部で,『問題解決のための「アルゴリズム×数学」が基礎からしっかり身につく本』米田優峻著からの抜粋のように見えるが,ひょっとすると本当の著者はChatGPTなのではないだろうか?いかにもChatGPTのやりそうな間違いだ.

「GPU上での高速なブロック化フロイド・ワーシャル法」などというのもあり,かなり実用的に使われているアルゴリズムではあるようだ.

https://cir.nii.ac.jp/crid/1050564287852717824?fbclid=IwAR2oMq0IYmoIrE51iR163SnZNPBA-mxKVd9MzsPwBcowTvNgwBGhGZVwU3M

この記事では改良によって頂点数256~1024の場合は従来手法より高速化し,それ以上の場合は遅くなったと報告しているが,アリアドネの既存コードでは100点までしか計算できない.行列同型でもN=520を超えるサンプルではスタックオーバーフローが起きていたはずなので,500点を超えるサンプルを扱えるようにするのは難しそうだ.我々の目的からすれば,そこまで大きなサンプルは必要ないので,まぁ,500点が限界だとしてもとりあえず問題はないが…

アリアドネはFドライブのBACK2006-05-05/BABA_LABORATORYにある.このフォルダにはsamplesというフォルダがあるが,この中にはファイルが9452本も入っている.フォルダだけで13個もある.Narcissus,ないしNarkissosというフォルダが気になる.ハミルトン閉路問題ではないかという気がするのだが… 2002~2004年頃のものだ.どちらが最終版なのか?EXEのタイムスタンプはまったく同じなので時期は完全に一致している.前者はフォルダ数293, ファイル数19に対し,後者のフォルダ数は30.ファイル数は3566なので,おそらく,Narcissusを保存版としてくくり出したのだろう.

Narcissusのpublishというフォルダには,Narcissus.exeと一緒にELSIE.exeも入っている.このフォルダではELSIEとNAICISUSを並行して開発していたのだろうか?このフォルダのSOURCEにはELSIEのソースファイルしか入っていない.⇒走らせてみれば分かるだろう.

image

NarcissusというのはELSIEの一部だ.つまり,ELSIEはNarcissusを含んでいる.NarcissusはELSIEの機能のうち,グラフ同型検定に特化したものと言ってよい.ただし,この機能に関してはELSIEより少し詳細な設定ができる可能性がある.たとえば,表示モードを切り替えたり,ファイル形式の変換ツールが入っていたりする.まぁ,とりあえずはELSIEに含まれているものだけで十分だ.アリアドネのソースはVBだと思っていたが,C++だった.AriadneはELSIEとほぼ同等だから,準同型検定CSに組み組むのは難しくないと思われる.ただし,Ariadneを組み込むとこのプロジェクト全体の性格が大きく変化することになるので,フォルダ名を変えておくのが順当だろう.

もし,今後ハミルトン閉路問題が主題になるとすれば,日本語で「アリアドネ」ということでよいのではないだろうか?Ariadneの中にはAriadne100の他に,Asha, CounterStas, Hcp2Sat01というフォルダがある.Hcp2Satはハミルトン閉路問題をSAT(論理式の充足可能性問題)に変換するためのツールだ.CounterStasというのはよく分からないが,Stanislav Busyginとのやり取りに関係したものだろう.Ashaの中にはBlkblu.exeというのが入っているが実行できない.あとはBlkblu.cとテキストファイルが2本入っているだけだ.

Ashaというのは多分人名だと思う.確かにそうだ.Cソースの中に

printf(“\n%s   v. %d, by Asha Goldberg\n\n”, progname, versionno );

という一行があるので,Asha Goldbergという人物が書いたコードだということが分かる.この頃はネット上にソースが転がっているという時代ではないので,多分本人から送ってもらったものではないかと思う.ただし,メールの現物は残っていない.このコードはハミルトン閉路の解法アルゴリズムだ.いや,ハミルトン閉路を含むグラフを生成するためのコードかも知れない.ブラックとかブルーなどの色を頂点に割り当てるようなことをしている.おもしろそうだが,読み切るにはちょっと時間が必要なのでパスしておこう.データファイルのフォーマットはアリアドネと完全に同じ,各行が#で始まる隣接行列だ.

ELSIEを組み込んだときの手順を忘れてしまった.既存のプロジェクトを組み込むというのが最速だが,新規プロジェクトとして登録してからファイルを追加していったような気もする.その辺り,ログに残っているだろうか?ELSIEのときは,boostというライブラリの組み込みで立ち往生していた.ELSIEのプロジェクトファイルはElsieComeBackフォルダに入っているので多分既存プロジェクトを組み込んだだけだと思う.その後,ソースファイルの入れ替えをやったような記憶もあるが… それよりも,Ariadneに入っている本体以外のフォルダを削除してディレクトリを1段上げておいた方がよい.つまり,アリアドネの直下にAriadne100が来るという構成だ.

準同型検定CSというソリューション名も変える必要がある.名前の変更は調整できたが,ビルド→実行でエラーが出てしまった.

image

アプリケーションのシングルスタートアッププロジェクトがElsieComeBackになっていた.準同型検定に変えて動作するようになった.⇒既存プロジェクトの追加で以下のメッセージが出た.

image

OKでビルドできたが,「D8016    コマンド ライン オプション ‘/ZI’ と ‘/Gy-‘ は同時に指定できません」のようなエラーになった./Gy-というのは,関数レベルでリンクしないという意味のようだ.ZIはエディットコンティニュの意味だ./Gy 関数レベルでリンクするに統一した.

i, j, k が定義されていない,ないし,未使用という警告⇒対処した.

warning D9035: オプション ‘Gm’ の使用は現在推奨されていません。今後のバージョンからは削除されます。⇒最小リビルドを有効にするという意味だ.⇒オフにしておこう.

▲This function or variable may be unsafeがかなりの件数ある.fopen, scanf, getch, strcpy, sprintf, ctime, strcpy,.. などだ.

MAXNを520まで拡大してスタックオーバーフローが発生

▲MAXNを520まで拡大して,スタックオーバーフローが発生した.ExcentricGraphでMakeRandomGraphの後,Shuffle関数の呼び出しができない.プロセスメモリは200MBくらいしか消費していない.MAXN=400なら動する.500でも動いている.⇒Shuffleの引数を参照からポインタに変えてみたが,スタックの使用量は減少していない上,Shuffleの中でGP例外が発生した.一度修正を元に戻すことにする.

またまた,横道に逸れてしまう

またまた,横道に逸れてしまう.FBグループの黒木氏がコメントで紹介しているグラフの距離行列生成アルゴリズムに疑義があり,動作を調べなくてはならないことになってしまった.「フロイド・ライブネッツアルゴリズム」というのを紹介している記事だが,わたしの推測ではコードとしては不完全なものであるように見える.「動的計画法」を用いているというのだが,さっぱり「動的」には見えない.単純にループを3回回しているだけなので,グラフが大きくなると解けないサンプルが出てくるのではないかという気がする.ただし,断定することはできないので,とりあえずプログラムを起こして走らせてみるしかない.

プログラムはすでに出来上がって,動いているので,後は適当なサンプルを食わせて試すだけという段階だ.その前に「距離」ではなく「離心数」を計算するように改造して試してみた.離心数というのはグラフ上の2点をつなぐ最長パスの長さを意味するので,この問題が解ければハミルトンパス問題が解けたことになる.ハミルトンパス問題はハミルトン閉路問題と等価なので,これが解ければ100万ドルが入ってくる.さすがに,こちらの方は最短パスの長さを計算するほど易しくはないが,この線で解ける可能性はゼロではない.手元の問題が片付いたら,調べてみる価値はあるだろう.

Test.txtを読み込ませてEccentricGraphを実行すると,処理後に「Input the first data file name」に出てしまう.これはFileComparisonの冒頭にある.case 文でbreakが墜ちていた.

動作が少しおかしい.以下のサンプルで

     1  2  3  4
1:  1  1  1  1
2:  1  1  1  1
3:  1  1  0  1
4:  0  1  1  1

距離行列に∞が表示されている.

     1  2  3  4
1:  0  1  3  3
2:  1  0  2  2
3:  3  3  0  2
4: *  1  3  0

最初の隣接行列からすでに間違っている.

#1 > 2 3
#2 > 1 3 4
#3 > 1 2
#4 > 2 

MatはVnというパラメータを持っている.これが決まらないと正しく動作しないというのはまずいと思う.clearmatではMAXNを与えている.引数のnの範囲を初期化するようにした.これで隣接行列は正しくなったが,距離行列はまだおかしい.初期状態で①ー④と③ー④の間には∞が入っている,ここまでは正しい.⇒修正ミスだ.ECCENTRICITYのところをINFINITDISTANCEで書換えていた.⇒動作するようになった.

歯磨きが切れてしまったので,自作した

歯磨きが切れてしまったので,自作した.

IMG_20231002_193401

材料は,塩,乾燥剤,片栗粉,石けん液.乾燥剤のストックはあるが,成分表示がないものが多くどれにしようかと迷ったが,石灰と明記してあるものが一つあったのでそれを使った.香料が入っていないのは残念だが使用感は悪くない.ただし,腔内の傷口にはかなりしみた.唇が膨れ上がるというほどでもないが,連用してどうなるかは未知数だ※.

※さすがに,ちょっと無理っぽい.以前炭の入った乾燥剤を使ったときは結構うまくいったのだが… アルカリ度が強過ぎるようだ.

またブランクが空いてしまった.こんなペースではいつ仕上がるのか見通しが立たない.やればやるほど,FBの物理数学グループに費やす時間が増えてゆく.開きっぱなしのVSを閉じて再起動したら,エラーが出ている.どこまでやったのかも忘れてしまった.問題は「C#からC++への配列の受け渡し」だ.型名[] 変数名のような形式で宣言されたC#の配列はC++/CLIに移すことができない.とすれば,std::arrayなどを使うしかないのだが,arrayの二次元配列をうまく作ることができなかった.一次元配列ならマーシャリングすれば受け渡しはできそうだ.いや,多分,その辺りはクリアされていると思う.

unsafe というのを使うしかないのかもしれない.unmanaged というのもあり,これを使えばアンマネージドコードの中でポインタが使えるようになる.もしかするとこれが一番早いかもしれない.もし,C#でポインタが自由に使えるということになれば,マーシャリングなどという厄介な話は泡沫もなく消えてしまうのではないか?もちろん,それだけのリスクは伴うものであるかもしれないが… もうひとつ,fixed というキーワードもある.後事のため,コードをコピーしておこう.

unsafe static void MemSet0<T>(ref T x)
where T : unmanaged
     {
         // 今まではこの T* が許されなかった。
         // たとえ、Point みたいにポインター化可能な型で MemSet0<Point> を呼んだとしてもダメ。
         // unmanaged  制約のおかげで、ポインター化可能になった。
         fixed (T* p = &x)
         {
             var b = (byte*)p;
             var size = sizeof(T);
             for (int i = 0; i < size; i++)
             {
                 b[i] = 0;
             }
         }
     }

おそらく,これを使えばかなり自由に配列のコピーはできると思うが,配列の内容がstringのような場合はまたかなり話が変わってくる.将来的にはString配列まで使うようになる可能性は高いので,対処しておいた方がよいと思う.その意味ではやはり array を使うという選択肢になるのだが… 以下の記事を読むとC#ではこれまで禁止されていたほとんどのネイティブ操作がどんどん許されるようになっているように見える.さすがに,C#周辺のプログラマも我慢しきれなくなってしまったのだろう.良い傾向だ!いよいよ馬場研究所の日が来るのかも知れない.

https://ufcpp.net/study/csharp/sp_unsafe.html#how-unsafe

つまり,C++でしか書けないと思っていた当研究所のオリジナルコードをC#で書ける日が来るのではないか?いや,さすがにオリジナルコードをC#で書くのは無理としても,C#の中から自由にそれらを呼び出せるようになるだろう.つまり,マネージドとアンマネージドを隔てていたベルリンの壁が崩壊する.やったね!この辺りの事情に詳しいのが,++C++; // 未確認飛行 C というサイトだ.このサイトは一度じっくり目を通しておいた方がよいかも知れない.

https://ufcpp.net/

一応何とかなりそうだという感触は得たが,まだコードは通っていない.二次元配列の受け渡しをやっているサンプルがどこかにあればよいのだが… もっと基本的なところから(一から)やった方がよいのではないか?いや,ジェネリックなデータの受け渡しはすでにやっている.たとえば,Stringというデータ型はC#でもC++でもそのまま使える.従って,問題はやはり配列の操作だ.とりあえず,C#の二次元整数配列の受渡しを見てみることにしよう.

C#の2次元配列をC++に変換する

まず,MatrixIsomorphismの引数をMatからint[,]に変えておこう.⇒引数に int[,]が使えない.昨日見た記事では確かにできるようになっていたと思うのだが…

https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/builtin-types/arrays

確かに,以下のような構文は認められている.

static void Print2DArray(int[,] arr)

ただし,これはC#の話だ.C++で可能かどうかは,また別の話になる.C++では最初の次元の要素数しか省略できない.ただし,下記のような呼び出しは可能なようだ.

int sum_all2(int size1, int size2, int arr[size1][size2])

ダメだ.コンパイルエラーになる.「C99だとこんな書き方ができるんだそうな」とあるのだが… 

https://qiita.com/Hiraku/items/babed27bc1d750c2e12d

C99というのは,1999年規格ということだから当然搭載されているものと思われるのだが… 以下の構文ならよいという記事があった.

static void sub_func( int (*a)[]

http://murakan.cocolog-nifty.com/blog/2011/08/cc-b731.html

確かにこの文は通る.ただし,アドレス計算を自前でやらなくてはならないというのが欠点だ.C++ではarrayとvectorが使えるはずだが,これらはどうなっているのだろう?arrayはサイズ固定の配列だが,vectorは可変長なのでこちらの方が使い易い可能性はある.どちらも多次元配列を作ることはできる.将来的には文字列を要素とする行列なども扱うようになる可能性があるので,arrayないしvectorを使うのが上策なのではないだろうか?処理速度ではarrayの方が速い.

配列サイズが変化するということはあまりなさそうだし,変化した場合にはそれなりの対処策もあるので,arrayを使うというのが現時点では妥当なのではないだろうか?なぜだろう.ElsieProject.hでデータ・タイプ arrayを宣言できない.同じブロックで関数の引数としてなら使えているのだが… 下記の構文なら一応通る.

int MatrixIsomorphism(int N, std::array<std::array<int, 12>, 12> m1);

しかし,

int MatrixIsomorphism(int N, std::array<std::array<int>> m1);

は通らない.以下は通った.

int MatrixIsomorphism(int N, std::vector<std::vector<int>> m1);

しかし,この形式ではC#で定義に使えない.c#にもVectorというのはあるが,これは「倍精度実数の対」というまったく別物だ.C#とC++をシームレスに繋ぐとしたら,今のところint[,]しかないのではないか?⇒C#の配列[,]はC++では読めない.やはり,マーシャリングが必要なようだ.ゼルコバの木ではこのようなときにどうしていたのだろう?ゼルコバの木には2次元配列というのはなかったかもしれない…

ELSIE の array クラスを廃止した

なぜだろう?主画面のウィンドウをドラッグ移動できない.最初に写像の検査を実行した後,フリーズ状態になっている.⇒入力待ちになっていただけだ.

Stringからchar*への変換がうまくゆかない.どうしても,Marshalingという操作が必要なようだ.ゼルコバの木のコードを見ると,この辺りではncopyNameという自前の関数を作って処理している.この関数ではまず,UNICODEをS_JISに変換するということもやっている.コード変換は必ずしも必要ないのではないかと思われるが… やっと動くようになった.以下のコードでString→char*の変換を行う.

pin_ptr<const wchar_t> pinchars1 = PtrToStringChars(file1);

内部で使っているISOMORPHなどへのアクセスを回避するため,NATIVEFUNC_API int ELSIENATIVE::MatrixIsomorphism(int N, Mat& m1, Mat& m2)のような関数を使って呼び出すようにした.一応何とかこなせたのではないかと思う.ただし,エラーが出ている.

MatrixComparisonを実行して,EchoingMethodで-1026エラーが発生している.FILENOTFOUNDだ!エンコードの問題とも考えれるが,文字列にエスケープ文字が入っていることが障害要因になっている可能性もある.Replaceを試してみたがうまくゆかなかった.残っている文字列は”D”だけなので,エスケープの問題というより,エンコードの問題ではないかという気がする.WcharからSJISに変換してみよう.

どうもいろいろ厄介なところがある.arrayというテンプレートクラスにアクセスできない.これはおそらく,ELSIEでarrayというクラスが定義されているためではないかと思われる.これはリネームしておくしかないのではないか?⇒対処した.これでncopyNameも動作するようになり,ファイルを読み込んで処理することができた.⇒これで標準のarrayクラスが自由に使えるようになった.

現行では,typedef int Mat[MAXN+1][MAXN+1];というのを使っているが,これも一般のarrayに置き換えておこう.ELSIENATIVEでは,ReadMatrixとMatrixIsomorphismがMatを使っている.⇒マトリックスはファイルから読み込んでいるので,最後まで読まないとマトリックスのサイズが判明しないが,読みながら行列に書き込んでいるので,あらかじめサイズを指定するか,ないし固定サイズの配列を用意するしかない.⇒MAXNを定数としてそれを超えるデータは読み捨てでよいのではないか?いや,そもそもMatは2次元配列だ.

(多分)サイズを指定しないと引数には使えないと思う.しばらくは,このままで運用することにしよう.いや,配列サイズが不明でも引数として渡すことができる.これができるのなら任意サイズの配列としておいた方がよい.配列は初期化されていなくてはならないから,その情報からサイズを割り出すことができるのだろう.

再起動時にコンソールのサイズと位置を復元

ともかく,コンソールが出せるようになった.おめでたいことだ.参照した【ワレコC#講座】には再起動時にウィンドウのサイズと位置を復元する方法も載っていたので実装しておこう.やり方は,いつも我々がやっているのと同じ,プロジェクトの設定に保存するという方法だ.

https://www.wareko.jp/blog/c-sharp-form-application-save-restore-window-state-position-size

主画面の保存・復元はできるようになったが,コンソールの設定の取得・設定が分からない.フォームのプロパティにはコンソールという項目は存在しない.コンソールを開くためにやったことは,C#プロジェクトのプロパティで出力の種類をコンソールアプリケーションに切り替えたというだけだ.⇒いや,簡単にConsole.WindowWidthなどのプロパティやメソッドにアクセスできるようだ,

一応取得・復元できるようになった.初期起動したとき,デフォルトサイズで表示された後→復元という動作になっているのが,気になるが,対策は難しい.Form1のコンストラクタの冒頭で更新するようにしても,そのときはすでにウィンドウは開いた状態になっている.まぁ,これは,ここまでとしておこう.

このツールのタイトルを行列同型検定とした.元々は群の同型検定を行うために開発されたものだが,ELSIEを発掘したことで守備範囲が拡大したと言ってよいだろう.対象は正方行列に限定とし,群の乗積表,グラフの隣接行列などの具象行列では台集合は行と列の並びと一致するものとする.ともかく,ELSIEから行列の同型検定論理を切り出してC#から呼び出せるようにしてみよう.

現行ではそれをやっているのは,MatrixIsomorphismで引数は,(int N, ISOMORPH *p0, Mat& d0, ISOMORPH *p1, Mat& d1)である.Nは行列のサイズ,MatはMAXN✕MAXNの整数行列,ISOMORPHは位相同型オブジェクトで作業領域と見られる.

コンソールが出せた!完璧だ!言うことなし

アプリケーションのプロパティでマルチスタートアップという指定ができる.これを使えばC++アプリとC#アプリを並列実行できそうだ.⇒ただし,C++の出力をDLLからEXEに切り替えるとまた,いろいろな不都合が噴出してくる.もし,これをやろうとするのなら EXE 生成用のプロジェクトを別途作って,それ以外の部分をDLL化するしかない.⇒さすがに,そこまでやるとなると右から左という訳にはゆかなくなってくる.ただし,そうすることのメリットもある.処理を切り分けてライブラリ化するというのはいずれやらなくてはならない仕事のうちだ.⇒とりあえず,ここのところはパスして先を急ぐことにしよう.

C++アプリを単独で起動することはできる.このコンストラクタからC#のフォームを開くことはできないだろうか?⇒かなり難しいと思う.エラーが発生するのは仕方ないので,エラーが発生してもアプリをアボートしないようにエラー処理に手を入れておくことにする.⇒現行バージョンのVSは型検査が厳密になっていて,const char* を char* と混同することができないようになっている.文字列をスローしている場合があるので,それを受けるときは const char* で取る必要がある.とりあえず,大体動作するようになった.

コンソールとフォームを同時に開くことができるようになった.コンソールプロジェクトを立てて,マルチスタートアップを仕掛けたというだけのことだが,この2つのウィンドウが同時に操作できたら,確かにかなりおもしろいと思うのだが… printfを実行しただけではコンソールには何もでない.やはり,このウィンドウのハンドルか何かを取得してそれを使って操作しないと何もできないような感じだ.⇒コンソールハンドルを取得することは可能なようだ.⇒しかし,ウィンドウハンドルをもらってもどうすることもできない.多分ウィンドウのデバイスコンテキストまでは取得できるとは思われるが,そのあとは細かい描画処理になってしまう.⇒std:coutを取り出して再利用できるようになった.

std::ostream &conout = std::cout;
conout << “Native::ElsieCommand #####################”;

これをグローバル変数に入れてやれば,多分マルチスレッドで使い回しできるはずだ.⇒かなり,難しいが,参照して出力できるようになった.⇒いや,やっぱり後が続かない.std:coutは使い回しできないような作りになっているようだ.あきらめるしかなさそうだ.以前やったように,テキストボックスに表示するというのが可能最大限ではないだろうか?ただし,テキストボックスにはC#からしか書き込みできない.コンソールアプリはイベントループを持っていないというのが致命的だ.

こんなのがあった.【ワレコC#講座】Windows FormアプリケーションでConsoleウインドウに文字を出力する https://www.wareko.jp/blog/output-text-string-to-console-window-with-windows-form-application-in-c-sharp

これで行けるんじゃないだろうか?

まずい.どこか壊してしまったようだ.ソリューションを開いたときにエラーが発生するようになってしまった.

image

WrapperClass.csというファイルは作っていないのではないかと思うのだが… クリーンビルドして再起動でなんとか収まった.

【ワレコC#講座】ではコンソールを使う2つの方法を紹介しているが,最初の方法はうまくゆかなかった.コンソールは開けたが,書き込みもクリアもできない.書き込みはデバッグコンソールに出力されてしまうだけでなく,Console.Clearで例外が発生してしまう.2番目の方法では成功した.C#プロジェクトのプロパティで出力の種類をWindowsアプリケーションからコンソールアプリケーションに切り替えるだけだが,この状態で実行するとWindowsフォームが通常通り開き,同時にコンソールも使えるようになる.Console.Writelineで問題なく出力できた.

コンソール出力は主にDLL側でやっているので,あまり使い道はないかもしれないが,この設計は悪くないと思う.Console.Clearもその通り実行できた.いや,これはかなりよいかもしれない.Console.WriteLineだけでなく,ラッパクラスのprintfも動作している.つまり,コンソールに出力されている.これこそ望んだところだ.Debug.WriteLineをすべてConsole.WriteLineに切り替えることができるだろうか?それができるとほとんどELSIEと準同型検定が一体化したというのに等しい.

!いや,見事に出てくれた!

image

完璧だ!言うことなし.このウィンドウをフォームに嵌め込めたらさらによいのだが,そこまで求めるのはやや過大な要求というべきだろう.これでこれまでの作業が全部そのまま活きてくることになる.かなりおもしろくなってきた!いや,さすがにそう簡単には動いてくれないかも知れない.ELSIEコマンドを受け付けるところまではゆくが,データファイル名の入力に失敗した後の動作が悪い.完全な動作するところまで仕込むことができるだろうか?かなり難しそうな気はする.

使い方の要領というのもありそうだが… コントロールがどこにあるのか分からなくなってしまうところが欠点だ.カーソルを置いても何も入力できなくなるというのは,フォーカスを失っているという意味だろう.どうも,使いこなすのはかなり難しそうだ.入力を受け付けるというのを止めて読み取り専用とすればおそらく問題はなくなるはずだが…ともかく,ELSIEと準同型の統合という作業を進めるしかないだろう.

土壷にハマって抜けられない

土壷にハマってしまった.完全に足が止まってしまっている.何とかしなくては.何をどうすればよいか?boostはすでに止めてある.あとは,C++ → CLI → C# を繋げればよいというだけなのだが… 実際,ゼルコバの木では昔からやっていることだ.何がどうまずいのか?確かにC#は今回始めてだが,基本的にはVB.NETとコンパチと考えられるからそれほど高い障壁になるとも思われない.わたしもいよいよヤキが回ったか?

C++で「重大度レベル    コード    説明    プロジェクト    ファイル    行    抑制状態 エラー    C2338    2 フェーズの名前参照は、C++/CLI または C++/CX ではサポートされていません。/Zc:twoPhase- を使用してください    ElsieComeBack    D:\準同型検定CS\ElsieComeBack\c1xx    1    」が出ている.

ようやく通った.ここまで来れば,あとはもうもらったようなものだ.⇒ようやく動いたと思ったのも束の間,またエラーが出てしまった.

▲ELSIEのコマンド2を実行して例外が発生した.

image

ELSIEはもともとコンソールアプリとして開発されていて,コンソール入出力なしでは実行はほとんど不可能だ.たとえば,ファイル名の入力を促すプロンプトが出て,ファイル名を受け取ったあと,処理の結果をダンプするなどの動作になっている.ファイル名が無効なら例外をスローするような作りになっているから,例外は当然のように発生する.フォームとコンソールを併用するか,ないしフォームでコンソールを代用するようなことはできないのだろうか?⇒不可能ではないかもしれない.コンソールアプリからフォームを開くことはできそうだ.

using System.Windows.Forms;

        [STAThread]
         static void Main()
         {
             Application.EnableVisualStyles();
             Application.SetCompatibleTextRenderingDefault(false);
             Application.Run(new Form1());
         }

プロジェクトのプロパティを変更し,

  • アプリケーションの種類(A)をコンソールアプリケーションにする
  • スタートアップオブジェクト(O)を Sub Main にする

ことで実現できる.これはやってみる価値はあるのではないだろうか?ELSIEの中身をすべてC#で書き換えるというのは現実的ではない.

まだCLI→DLLの接続はできていない

ELSIEにラッパクラスを追加するところまではできるのだが,そのクラスにメソッドを追加したところで,E0035が発生してしまう.重大度レベル    コード    説明    プロジェクト    ファイル    行    抑制状態 エラー (アクティブ)    E0035    #error ディレクティブ: “This library now requires a C++11 or later compiler – this message was generated as a result of BOOST_NO_CXX11_REF_QUALIFIERS being set”    ElsieProject    C:\Users\babalabo\vcpkg\installed\x86-windows\include \boost\multiprecision\detail\check_cpp11_config.hpp    34

メソッドをヘッダファイルではなく,CPPファイルに実装したら,エラーは解消した.ただし,C#でラッパクラスの名前空間を参照しようとすると,同様のエラーが発生してしまう.C#プロジェクト→参照の追加→ElsieProjectで namespace ElsieProjectにアクセスできるようになった.⇒いや,まだ通っていない.C#からラッパクラスの関数にアクセスできない.⇒どうも,やはりboostとの相性が悪いように思われる.boostを完全に停止することでようやく一通りのことができるようになった.つまり,C#からC++/CLIの関数が呼び出せるようになった.ただし,まだCLI→DLLの接続はできていない.