星田オステオパシー

プログラミング学習日記 2024/03/04〜


2024/03/12 お気楽Prologを更にやっていく
 昨日は昼間に時間がなく、借りてる本も読まないといけないし、夜はなんか疲れてしまってProlog学習が出来ませんでした。まあ、朝にBlog書く時に復習してるようなものなので全くやってないわけでは無いのだが!

 Prolog学習を続ける前に「もしかして僕ってPrologが嫌いなのでは?」と不安になる。好きなら疲れたとか関係無いから!というわけでLRでチェック。
 プログラミングー>OK
 Prologー>NG! やっぱりな
 というわけでLRで思考修正「Prologが大好きである」がバランスするまで調整する

 Appendの続きから。おおっ!?自由変数を変更することで、別の引数部分を割り出すことが出来るのか!確かに理屈から言えば「そうなるよな」と理解できるんだけど・・非常に面白いですねぇ!


 うーん、ムズい。ルールの中に別のルールが入った再帰パターンは初めてなので、どういう動作をするのか全くわからない。「プログラムは簡単です」って一言が追い打ちをかけてくるw
 うーん・・Head部の第二引数Ysが探索して望む値?になるので、最終的にそれを出力するようにBody部を組み立てると・・基本になるのが再帰のXs,Zsで、Appendも不確定の自由変数Ysを探索するはずなので・・なんとなく分かるような分からないような


 Claudeに動作を説明してもらうと・・再帰で潜っていって停止した状態になったところでAppend開始か・・しばらくはこのパターンって事で覚えておくしか無いか。数をこなせば理解出来るときが来るはず


 練習問題、Copyは正解出来たが


 リストの要素を合計するSumlistは不正解。上が自作、下が解答例。
 うーん、Bodyの計算でA1とAを間違っているのが原因。Bodyの再帰部分がA1なのでLet的にA1に束縛するように思ってたけど、Head部分の条件を満たすってことだからか?束縛すべきはAだったと?


 続いてリスト内の最大値を返すMax。うーん、不正解。
 X>AだったらA1にXを束縛して・・とかいきなりSumlistでの教訓活かせてないから。そしてそれ以前に場合分けの場合は1つのルールでこなす必要はなくて都度別のルールを作れば良いのか、とか。


 気になったので終了条件を変えてみる。空になった時に0で良くない?と。結果、OKでした。まあでも解答が正しいな


 練習問題が終わって次へ。Memberの実装・・これで出来るんか〜(-_-;)
 まあ、引き続き学習続けます。


 宿直先では座ってサイトを見るのがしんどい(高さが合ってない)ので練習問題以外の時にはPCを倒してベッドに寝転がりながら行うことにしました。
 結果、すごく良く眠れました




2024/03/10 お気楽Prologをやっていく
 練習問題の続きをやっていく。リストの最後の要素を返すMy_lastを書けという。書けそうじゃないか?と思ったが書けないw
 解答を見ると・・あ、なるほどな〜・・読んだら「なるほど」と思うんだけど書けない。[x], Xでリストの要素が1つだけだったら・・ってのも言われたら「そうね」と思うけど発想がなぁ〜


 そしてAppend。この行は分かるんだけど(しかし後に根本的に勘違いをしてたことが発覚する)


 なんでいきなりXsが出てくるの?と。第2引数は上の行で言うところのYだから、Yでエエんじゃないか?と。つまり、今から考えるとルールのルールを分かってなくて、やっぱり上から順番に処理されてると思ってるんですよね。なので実引数の2番めの要素(今回はリスト)が1行目でYに束縛されてるんだから[], Y, Yと書けば1行目の第2引数、2行目の第2引数、2行目の第3引数と束縛の連鎖が続いていくと思ってたわけ


 ん〜・・いや・・ちょっと質問が悪かったかな。Xs = Ysの=はEqual?って話なのかってんじゃなくて束縛されてるんじゃないのか?って事を聞きたかったのだが・・。つまり、変数の名前がかぶってても値は参照されて無いんじゃないのか?って事が聞きたいわけ



 !!


 
 なんだよそういう事か〜・・なるほど段々と「理解できてない原因」が絞れてきたぞ。
 とことんパターンマッチってのが分かってなかった。実行時に不確定(自由変数)である第3引数にマッチする値を探してるので、実質的には2行目の第3引数には第2引数が束縛されることになる(じゃないとマッチしてないから)ってことか。
 で、1行目で再帰してるから、ここからやっとこさZsが確定してXsがケツから合体して行き、Zsがあるべきマッチ状態を組み上げると・・。

 うーん、分かりかけて来てる気がする。まあ、気がするだけだけだろうけど。引き続きProlog学習します。


2024/03/09 
話題その1 お気楽Prolog、なんかパターンが浮かんできたかな

 リストの練習問題。こうか!?と思って書いたのが上、下が解答。
 おっ!?ほぼ合ってる!そうか終了条件の段階でのSをリストに入れておかないといかんか。あと、終了条件の第2引数がSだと・・?


 うーん、別にEで良い気がするんだけどなぁ


 続いてTakeの実装。上が自作で下が解答。ヘッド部の変数の分け方が分かってない。そしてもう一つ問題は終了条件の第一引数か・・都度変化するから_にしてスルーさせないといけなかったか。Nが0より多いってので判定はオッケイなんだから。第3引数は今度は空リストか〜


 続いてDrop実装。これは全く手も足も出なかった・・[_ | Xs]でCar部をどんどん削除していけるとは・・。

 なるほどな・・再帰系のルールとしては
・関数に使う変数を決める:元になるデータ、カウンタ、出力用自由変数
・ボディ部の変数はカウンタだけを更新用にして残りを素のままで書く
・ヘッド部の変数を変化させたい形に組み立てるテンプレート的に書く
・終了条件で判定部分は変数、スルーする部分は_、アキュムレータにする部分は基本的に空リストでOK、と。


話題その2 Prologが終わったら今度こそマクロに挑戦だな!





2024/03/08 お気楽Prologをやっていく
 関数?の造りがさっぱり分からないのでClaude先生に一応解説をお願いする。
 うーん、見た感じ想像してたよりはかけ離れていないような?
 x>0はループの条件だし、X1 is X - 1はループのステップ、新たな変数での再帰があって演算結果を新たに束縛・・そしてなぜに別になってるのかはまだわからないけど終了条件としてfact(0, 1)と。
 文法的には,で区切られてるのはAndなので全部がTrueかをチェックしてるっぽいが?


 一応先生に問い合わせをしてみる。


 お、やっぱりな。そして並びは可読性の為だったか。確かに「なじみのある流れ」だと感じたので大いに効果があるかと


 なるほど・・とは言いつつ明らかに理解しきってないのを自分で感じるな。再帰の関数はこういう風に書くんだ、と形で覚えることは出来るけど。上のボディ付きの方がFalseとなった時点でfact(0, 1)が呼び出される気がするんだけど、じゃあなんでそれで本体ありのFact(... に適用されるんだ?と。ここらへん、今までの言語の考え方が抜けてないんだろうな、と。まあ、Schemeの時も「いつの間にか」分かるようになって来てたし、言語の理解ってそういうものかもな?とりあえず続けよう


 
 WEB版のSWISHでリスナー部分を使ってちょっと遊んでみる。例文をそのまま打ち込むと・・・ふーん。=が束縛とか代入で無いとか何とか?なんだ?


 Xが非表示になってたので表示するようにしてみる。値は1+1か・・うーん環境がそのまま入ってるってことか?


 とりあえず聞いてみるか・・。
 ふーん・・というか、なんで複数の機能を持ってるんだよ。1つの関数に1つの機能、スタンドは一人に一体がルールだろ〜
 2つ目は・・いわゆる束縛っぽいな。Xが無束縛だったら束縛済のYと同じになる?1つ目と3つ目の解説を求む


 はぁ・・これって意味ある?



 やっぱ意味ないんかーい!


 なるほど?


 なるほど・・同じファンクタ限定の高機能なEqual?述語って事か?


 まあ結局のところ、=の述語ってことかな


 実際のところ=とIsでどう違うのか実験するか


 Isだと計算結果を束縛してると


 =だと式をそのまま束縛してると


 自由変数Zに数値が計算された結果が束縛されると。まあ、なんとなく分かったかな


 色々といじっててようやくエディタの使い方が判明する。左側で新たなタブを開いて、Programを選んでコードを書くことが出来て右下で実行が出来て、その上に結果が出力されると。楽しくなってきた


 練習問題をやってみる。うーん、こういう感じ?例文を改変して書いたので書けてるけど、ゼロからだとまだ怪しい


 X乗の合算、こうかな


 解答。えっ!?sum1(N, A) :- A is N * (N + 1) // 2.って・・あ、別解か。


 解答。別解は・・・別にエエか。


 これが分からなかった。コードの最後の行pow(2, 0, 1).としてますが、解答では_となってる。ここにXを入れるとエラーなので、しょうがなく実引数と同じ数値を入れて何とか動いてるわけだが・・



 はぁ〜・・なるほど。終了条件も実行時に任意に決められる場合にはこうしないと駄目ってことか・・覚えておこう


 Fizzbuzzは全く思いつかず。あ、これは・・・なんとなくこれが出来るならBrainfuckも出来そうな気がするな。
 ふーむ
・予め述語用のテンプレートを作っておいて
・Fizzbuzz関数の中で未定義の変数Sを探索するように書いてChangeを呼び出して
・出力用のSはChangeで束縛済みのを流用して(ってことでいいのか?)
・Changeでマッチしなかった場合は再帰で次のテンプレートをチェック

 こんな感じだろうか?



2024/03/07 Prologの入門ページを読んでいく
 最初Claude3先生にコードの解説をしてもらうことで学習をしようと思ったが・・やっぱり体系立ってるページを読みたいと。公式は英語だしなぁ・・


 探しているとどこかの大学の講義のページに行き着く。おお・・しかし3日分しかデータがない。課題が出てるんだけど解答・解説は授業でやる予定だったのか載ってないし・・何しろ古い。WindwsXPにインストールする方法とかが解説されてるし。
 ちなみにリストの上はリストの解説部分。おお、Consやん!


 探索プログラムの例。ふんふん、少なくともこういうことは出来るのか・・とにかく今までの力技というか・・なんとかして動けば良いやってのは通用しない言語やな、と。データと処理の設定(ファクトとルール?)のをガッチリ論理的に設計しないとどうしようもなさそう。


 もうちょっと分かりやす解説無いのか・・と探してたら、なんとお気楽さんが作ってくださっていた!

 というわけで読んでる最中最中なのです。今のところ、これでBrainfuck的なものを書ける自信は全く無いですねぇ!


2024/03/06

 ジェネレーターが気になったのでRacketで同様の機能があるかと聞いてみると・・ここで継続か!


 Pythonのジェネレータに関してはコードを見る限りReturnの代わりにYieldを返すように書けば勝手にジェネレータになるっぽいのでパワーアップしたというClaude先生に聞いてみる(先日2から3に上がってGpt4を超えたという謳い文句)。
 まあ、Claude先生が正しいとすれば、この理解で大丈夫なようだ


 で、折角なので関連があるという継続をこの際だから勉強してみるか・・


 書かせたコードを見る限りでは大域脱出のパターンの最後に変数を更新してるってだけっぽい?


 ほーん・・なるほどね!


 折角なのでいっちょ例文を書いてくれ!と頼んでみる。ちゃんと継続になってないバージョンも併記してくれるのが助かるなぁ(頼んでないのに)。
 この場合ではただの大域脱出と変わらように思えるけど・・・まあ、他にはジェネレーター的なものしか使いみちも思いつかないし、今日のところは「少しは理解が進んだ」って事で良しとしよう。

 あとはPrologの入門ページを読んでました。


2024/03/05 PythonでBrainfuck、一応完成

 [ ]でのコマンドリスト適用にFoldが必要なのでPythonでのReduceの使い方を調べる。


 とりあえず[で始めて]でそれまで溜め込んだコマンドを一気に適用するという例の方法をやってみる。



 オッケイ!問題は−でループの回数をコントロールする部分だけど。Racketでの2重ループで外側から検知ってどうするか・・



 結局、内部の関数の中に更に関数を作って(Let loopみたいな感じで簡易に各方法があるのかも知れないけど・・今はとりあえず動けば良いかって事で)、外部に保存しておいた元のCommand_listをPointer部の数値が0になるまで繰り返すって感じで?


 なんといきなりちゃんと動いてしまったんだな、コレが


 退勤まで時間があったので入力時に想定外のコマンドが入ったときの対処を例外処理で書く。すごく分かりやすい文法で気に入った!


 まだ時間があったので連続入力部分も書く。こっちは引数が2つ必要なので一緒にまとめることは出来ないか・・と思ったんだけど、考えてみたら他のc_minusとかも同じ形にすれば・・あ、でも辞書でのピックアップで+++とかってのを拾えないか・・辞書部分で正規表現が使えればできそうだが?



 実験、成功。おお〜出来たで!そして確かにちょっとはPythonに慣れることが出来た気がする。
 うーん、折角なのでこのままPrologとRustでもBrainfuckに挑戦してみるか・・Prologのあの仕組みでどうやってプログラムが動くのかが非常に気になる。




2024/03/04 
話題その1 PythonでBrainfuck
 Dive into Pythonを読みながら進めようという予定だったけど、面倒になっていきなりBrainfuckを書き始めてしまう。結局Racketで書いたものを翻訳するカタチになりそうだし、書き方がわからないときにはWRTN教授に聞くって感じで(Cametanさんがおっしゃって下さってるように自然言語で検索してる感じですわ)
 しかし上のコード・・Returnの後に(が入れたくてしょうがない。他は慣れそうだけど、ここは気持ち悪いなぁ


 クロージャを書いていきまして・・・あ、<とか-とか,とかがシンボルとして使えないのがちょっと不便ですかねぇ


 場合分け部分。Brain_readって名前はおかしいような気がするけど・・結局内部でEvalもLoopもしてしまうからなぁ・・ま、エエか。


 [ ]はまだ実装してないのですがとりあえずテストしてみる。うーん、ここまではOKかな?
 あとは[ ]と連続入力部分か・・


 クロージャをリストに入れて・・ってのが出来るかチェック。
schemeで言うところの
(define test (lambda (test) ...) ...
 という変数にクロージャを閉じ込めるってのをやりたくて。ほ〜ん・・クロージャって言うか普通に引数なしの形で関数を入れてるだけって感じだけど、こう書くしか無いのか。動けば良いんだけど。

 ところでこの場合分けの部分、辞書形式で呼び出すようにするべきだったわ。書き直す事にしよう。


話題その2 CametanさんのAI話
 ガビーン!なるほど・・てっきり、何度も「動かないんですが」「こういうエラーが出ますが」とかってやってれば「オッケイでした」というリアクションがあった時点で少しは更新されるのかと思っておりました。駄目なことは何回聞いても駄目な可能性が高いのか〜。メジャーアップデートが行われる時点でどういう処理をすんのかなぁ〜・・まさか学習の範囲を「広げる」だけだとしたら

 これはずっと解消出来ないっぽいですよねぇ・・。内部で環境をエミュレートして(それこそテスト駆動開発的に)無限に演算を繰り返してテストに通ったコードだけを返してくれるとかって風にはならんのかなぁ。


話題その3 Idleのアイコン
 アイコンの切り抜きが雑すぎてダークモードだと使いにくい!

  • Xでシェアする
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

最近の「プログラミング」カテゴリーもっと見る

最近の記事
バックナンバー
人気記事