【问题标题】:graphically plotting lisp code以图形方式绘制 lisp 代码
【发布时间】:2023-04-05 20:32:01
【问题描述】:
关于一个 GP 项目,我有很多自动生成的 lisp sn-ps,它们基本上看起来像这样:
(+ 2 (f1 (f2 x y) (f2 x y)))
简而言之:大量单行。
如何将其以图形方式绘制到函数树中?最好通过在 dot 或类似的东西中生成图表,这些图表可以很容易地通过 graphviz 推送,这样我就可以将它渲染成这样的东西:
+
/ \
/ \
2 f1
/ \
/ \
/ \
/ \
f2 f2
/ \ / \
/ \ / \
x y x y
【问题讨论】:
标签:
treeview
lisp
graphviz
dot
【解决方案1】:
这是怎么回事(在方案 [Dr. Racket] 中):
(define (as-string elm)
(cond
((string? elm) (string-append "\\\"" elm "\\\""))
((number? elm) (number->string elm))
((symbol? elm) (symbol->string elm))
((null? elm) "*empty-list*")
(else (error "Unrecognized type"))))
(define (node-name-label names labels)
(apply append (map (lambda (a b)
(if (list? a)
(node-name-label a b)
(list (cons a b))))
names labels)))
(define (node-txt names labels)
(apply string-append (map (lambda (x)
(let ((name (car x)) (label (cdr x)))
(string-append name " [label=\"" (as-string label) "\"];\n")))
(node-name-label names labels))))
(define (graph-txt lst)
(apply string-append (map (lambda (x)
(let ((a (car x)) (b (cdr x)))
(string-append a " -- " b ";\n")))
(get-relationships lst))))
(define (declare-nodes lst (basename "node"))
(map (lambda (x n)
(if (and (list? x) (not (empty? x)))
(declare-nodes x (string-append basename "_" (number->string n)))
(string-append basename "_" (number->string n))))
lst
(range 0 (length lst))))
(define (get-relationships lst)
(if (< (length lst) 2)
null
(apply append (map (lambda (x)
(if (list? x)
(cons (cons (car lst) (car x)) (get-relationships x))
(list (cons (car lst) x))))
(cdr lst)))))
(define (range start end)
(if (>= start end)
'()
(cons start (range (+ 1 start) end))))
(define (get-graph code graph-title)
(let ((names (declare-nodes code)))
(string-append
"graph "
graph-title
" {\n"
(node-txt names code)
"\n"
(graph-txt names)
"}")))
用法:(display (get-graph '(+ 2 (f1 (f2 () y) (f2 x y))) "simple_graph")) 产生:
graph simple_graph {
node_0 [label="+"];
node_1 [label="2"];
node_2_0 [label="f1"];
node_2_1_0 [label="f2"];
node_2_1_1 [label="*empty-list*"];
node_2_1_2 [label="y"];
node_2_2_0 [label="f2"];
node_2_2_1 [label="x"];
node_2_2_2 [label="y"];
node_0 -- node_1;
node_0 -- node_2_0;
node_2_0 -- node_2_1_0;
node_2_1_0 -- node_2_1_1;
node_2_1_0 -- node_2_1_2;
node_2_0 -- node_2_2_0;
node_2_2_0 -- node_2_2_1;
node_2_2_0 -- node_2_2_2;
}