Archive for 2014年12月|Monthly archive page

FOOP で DAG する

 前回の DAG スクリプトは如何だったでしょうか?
 search-XXX なんて関数名は有りがちな名前。そんな時、関数名の衝突を避けるには FOOP(Functional-Object Oriented Programming )なんてもってこい。
 とは言え、newLISP の目玉でもある FOOP を使ってこなかった私。この辺で覚書きでも作っておこうかと、、、
 
 ということで、コードは、

(new Class 'MAIN:DAG)

(define (DAG:DAG lst)
    (list DAG lst))
(define (DAG:nodes)
  (self 1))
(define (DAG:search-pre)
  (letex (_x (args 0))
    (if (find-all '(? _x) (self 1)) $it "start")))
(define (DAG:search-next)
  (letex (_x (args 0))
    (if (find-all '(_x ?) (self 1)) $it "end")))
(define (DAG:search-all)
  (letex (_x (args 0))
    (local (res)
      (dolist (x (self 1))
         (if (match '(? _x) x) (push x res -1)
             (match '(_x ?) x) (push x res -1)))
      res)))

 ポイントは、オブジェクト・データ部分のアクセスが self になること。
 とわかっていても、私には慣れが必要かも。引数の扱いが、、、
 さて、使い方は、

> (set 'mydag (DAG '((a c) (b c) (c d) (c g) (d e) (d f))))
(DAG ((a c) (b c) (c d) (c g) (d e) (d f)))
> (:nodes mydag)
((a c) (b c) (c d) (c g) (d e) (d f))
> (:search-all mydag 'd)
((c d) (d e) (d f))
> (:search-pre mydag 'd)
((c d))
> (:search-next mydag 'd)
((d e) (d f))
> (:search-pre mydag 'a)
"start"
> (:search-next mydag 'g)
"end"
> 

 こんな感じ。

 以上、如何でしょうか?

newLISP で DAG する...または、match な find-all

 DAG (Directed acyclic graph) とは有向非巡回グラフのことらしい。
 といっても、DAG が何かわからずにコードを書いた私。
 きっかけは、newLISP Foram の投稿から。
 これは簡単にコード化はできそうだと思い、書いて投降したのですが、、、
 何か、しっくりこなかったのです。newLISP らしくないというか、、、
 同投稿で rickyboy 氏が findmatch を使っているのを見て、思い出しました。 find-all がリストに対して match になる(第二構文)ことを。

(if (replace nil (map (fn (x) (match '(? _x) x true)) lst)) $it "start")

 なんて、長ったらしいコードは、find-all を使えば、

(if (find-all '(? _x) lst) $it "start")

 ああ、すっきり。
 前にも、こんなことがあったのを思い出し、忘れないよう blog に(笑)
 先に newLISP Foram に投降したコードは、こんな感じに変わります。

(define (search-pre lst)
  (letex (_x (args 0))
    (if (find-all '(? _x) lst) $it "start")))
(define (search-next lst)
  (letex (_x (args 0))
    (if (find-all '(_x ?) lst) $it "end")))
(define (search-all lst)
  (letex (_x (args 0))
    (local (res)
      (dolist (x lst)
         (if (match '(? _x) x) (push x res -1)
             (match '(_x ?) x) (push x res -1)))
      res)))

 ついでに newLISP らしく、ifcond 的な使い方も(笑)

 以上、如何でしょうか?