AI::Prolog

perlの実装でAI::Prologというのがあるが、インストールするとaiprologというコマンドがついてくる。

階乗を計算してみる。

fact(0, 1).
fact(X, Sum) :-
    X > 0, X1 is X - 1, fact(X1, Sum1), Sum is X * Sum1.

aiprologを起動

$ aiprolog fact.swi

Welcome to AI::Prolog v 0.740
Copyright (c) 2005-2006, Curtis "Ovid" Poe.
AI::Prolog comes with ABSOLUTELY NO WARRANTY.  This library is free software;
you can redistribute it and/or modify it under the same terms as Perl itself.

Type 'help.' for for a list of built-ins or 'help("$builtin").' for help on a specific built-in.

?-fact(10,X).

fact(10, 3628800)

Yes

prologをいじってると宣言的ってのが「あーこういうことなのね」ってのがわかって楽しい。On LispでCommon Lispで実装するPrologとか読んである(継続とパターンマッチング)と内部でこういうことしてんのかなとか推測できるし。

ProductName On Lisp
ポール グレアム
オーム社 / 3990円 ( 2007-03 )


あとでHOPの9章の宣言的プログラミングのとこも読み返そう。Prologを知ってると面白く読めるのかも。

ProductName Higher-Order Perl: Transforming Programs with Programs
Mark Jason Dominus
Morgan Kaufmann / 5692円 ( 2005-03-28 )


HOP 9.4.1は連立方程式を制約システムで

久しぶりというか、ちょこちょこ読んでいるのだけどなかなか進まない。

ProductName Higher-Order Perl: Transforming Programs with Programs
Mark Jason Dominus
Morgan Kaufmann / 5976円 ( 2005-03-28 )


写経してみたけど、また戻ってきそうな予感。

制約システムで連立方程式を解く。

相変わらず継続

継続のあたりをうろうろしてますが、先週末に到着したOn Lispの継続の章をつまみ読みしてまたちょっと理解がすすんだような気がしたようなしないような。

ProductName On Lisp
ポール グレアム
オーム社 / 3990円 ( 2007-03 )


最後の方で、

継続

CPS変換を覚えればcall/ccを書くのは簡単だ. CPS変換を経たプログラムでは,全体に対する現在の継続が常に存在し, call/ccはその引数として何らかの関数を呼び出す単純なマクロとして実装できる.

と書いてあるのだが、perl - to goto or not to goto, that's the continuationの先にどうやればperlでcall/ccが実装できるのかわからん。

rubyにはcall/ccがあるらしいですね

そもそもCall/CCがrubyに実装されている理由はただ一つで、「実装できてしまったから」である。

モダンPerl入門

予約した

ProductName モダンPerl入門 (CodeZine BOOKS)
牧 大輔
翔泳社 / 2940円 ( 2009-02-10 )


数日前にどうしようかなぁと悩んでたんだけど、内容みたらすごく欲しくなった。

カウンターのクロージャ

common lispだと

(let ((count 0))
  (list
  #'(lambda () (incf count))
  #'(lambda () (decf count))
  #'(lambda () (count)))

同じことをperlでもlispっぽくかける。

#!/usr/bin/env perl

use Perl6::Say;

sub make_counter {
  my $c = 0;
  return (
      sub {$c++},
      sub {$c--},
      sub {$c}
     );
}

my ($inc,$dec,$counter) = make_counter();

say $counter->(); # 0
$inc->();
$inc->();
$inc->();
say $counter->(); # 3
$dec->();
say $counter->(); # 2

ProductName 実践Common Lisp
Peter Seibel
オーム社 / ¥ 4,410 ()
通常24時間以内に発送

Test::Continuous

Web+DB Pressに載ってた、ソースをセーブするタイミングでテストを実行するモジュール。

Test::Continuous

毎度手動で、make testとかしなくていいので便利に違いない。今度つかってみよう。あと、flymakeなんかを組み合わせるといいのかな。

というわけで、モダンプログラミング入門が面白かった。

ProductName WEB+DB PRESS Vol.48
WEB+DB PRESS編集部 編
技術評論社 / ¥ 1,554 ()
通常24時間以内に発送

今年は本をよく読んだ気がする

SICPからHOPへのコンボがperlを扱う上でとても役立った。

ProductName 計算機プログラムの構造と解釈
ジェラルド・ジェイ サスマン
ピアソンエデュケーション / 4830円 ( 2000-02 )


特にHOPは値段以上の価値があったと思ってるので満足。

ProductName Higher-Order Perl: Transforming Programs with Programs
Mark Jason Dominus
Morgan Kaufmann / 5976円 ( 2005-03-28 )


そしてMAWP

ProductName Mastering Algorithms With Perl
Jon Orwant
Oreilly & Associates Inc / 2716円 ( 1999-07 )


来年もこの調子で。あと、もっとコードを書く。

Lingua::JA::TFIDFとSearch::Estraierで類似エントリ検索

Hyper Estraier インストール(3) オリジナル検索エンジンの作成によるとややこしいことしなくてもクローラーとP2Pって連携できる。ちゃんと読んだらクローラガイドにも書いてあった。

というわけでP2Pの設定をしてテストしてみた

use Lingua::JA::TFIDF;
use Search::Estraier;

my $text = q(

    * 長い労働時間がより多くの成果を生み出す訳ではない。むしろ仕事と生活をうまくブレンドしたほうが生産性が上がる
    * 仕事人間は過度に会社に期待している、会社も期待しているだろうという思い込む
    * 生きること(living)と存在していること(existing)は違う
    * 働きかたを選べるようになるためには、まず自分のスキルを磨く
    * 少子高齢化で人口減少の社会では終身雇用は機能しない
    * 効率の良い働きかたの延長線上に豊かな発想は生み出されない、生活にゆとりがないとあたらしいアイデアはうかばない
    * 非正規労働者が増えると技能の継承ができないという危機感を抱くひとが増えてくる
          o これは経験した
    * 現在求められている成果量は長時間残業を前提として決められている
    * 時間、人生、自分自身についてのパラダイムがこの問題をつくりだしているのではないだろうか(p.224)
    * 足るを知る(Enough is enough)

);

my $calc = Lingua::JA::TFIDF->new;
my $result = $calc->tfidf($text);

my $query_keywords = "[SIMILAR] ";

for (@{$result->list(5)}) {
  my($key,$val) = each(%$_);
  $query_keywords .= "WITH " . int($val) . " $key ";
}

warn $query_keywords;

my $node = new Search::Estraier::Node(
                      url => 'http://localhost:1978/node/drkcore',
                      croak_on_error => 1,
                     );

# create condition
my $cond = new Search::Estraier::Condition;

# set search phrase
$cond->set_phrase($query_keywords);

my $nres = $node->search($cond, 0);

if (defined($nres)) {
  print "Got ", $nres->hits, " results\n";

  for my $i ( 0 ... $nres->doc_num - 1 ) {
    my $rdoc = $nres->get_doc($i);
    if( $rdoc->attr('@uri') =~ /entry/) {
      print "URI: ", $rdoc->attr('@uri'),"\n";
      print "Title: ", $rdoc->attr('@title'),"\n";
    }
  }
} else {
  die "error: ", $node->status,"\n";
}

実行結果

% perl test.pl
[SIMILAR] WITH 11 働き WITH 10 労働 WITH 8 成果 WITH 8 延長線 WITH 7 少子  at test.pl line 30.
Got 15 results
URI: http://blog.kzfmix.com/entry/1227393133
Title: 「ワークライフシナジー」読んだ
URI: http://blog.kzfmix.com/entry/1222936959
Title: 「発想の道具箱」と「ハイスピード仕事術」
URI: http://blog.kzfmix.com/entry/1226787565
Title: 「革新的ソフトウェア企業の作り方」を読んだ
URI: http://blog.kzfmix.com/entry/1221714188
Title: 系として壊れてきている?
URI: http://blog.kzfmix.com/entry/1221057705
Title: Maybeお仕事モナド
URI: http://blog.kzfmix.com/entry/1226148131
Title: 「あたらしい戦略の教科書」読んだ

あとはモデルに組み込めばOKな感じ。

Lingua::JA::TFIDFとCatalyst::Model::Estraierで類似エントリを探す

こんな感じで過去に書いた類似のエントリ出すようにしたい。

TF-IDFで特徴語を抜き出す。

my $calc = Lingua::JA::TFIDF->new;
my $result = $calc->tfidf($text);

my $query_keywords = "[SIMILAR] ";

for (@{$result->list(5)}) {
  my($key,$val) = each(%$_);
  $query_keywords .= "WITH " . int($val) . " $key ";
}

とやってクエリをモデルのほうに渡せばOKっぽいんだけど、Hyper EstraierのほうをP2Pで動かしてないんだったヨ。

イントラでクローラはしらせているのでじゃぁperlバインディングからでもと思ったが、ちゃんと入ってないっぽくてこけてる。

そのうちP2P対応させようということで、途中までのメモ。