egison-3.2.14: sample/graph.egi
;;;
;;;
;;; Graph demonstartion
;;;
;;;
;;
;; Matcher definitions
;;
(define $graph
(lambda [$a]
(set (edge a))))
(define $edge
(lambda [$a]
(algebraic-data-matcher
{<edge a a>})))
;;
;; Sample data
;;
(define $graph-data1
{<Edge 1 4>
<Edge 2 1>
<Edge 3 1>
<Edge 3 2>
<Edge 4 3>
<Edge 5 1>
<Edge 5 4>
})
(define $graph-data2
{<Edge 1 4> <Edge 1 5> <Edge 1 8> <Edge 1 10>
<Edge 2 3> <Edge 2 6> <Edge 2 12>
<Edge 3 2> <Edge 3 7> <Edge 3 9>
<Edge 4 1> <Edge 4 6>
<Edge 5 1> <Edge 5 8> <Edge 5 9> <Edge 5 11>
<Edge 6 2> <Edge 6 4> <Edge 6 10> <Edge 6 12>
<Edge 7 3> <Edge 7 9> <Edge 7 11>
<Edge 8 1> <Edge 8 5>
<Edge 9 3> <Edge 9 5> <Edge 9 7>
<Edge 10 1> <Edge 10 6> <Edge 10 12>
<Edge 11 5> <Edge 11 7>
<Edge 12 2> <Edge 12 6> <Edge 12 10>
})
;;
;; Demonstration code
;;
;; find all nodes who have an edege from 's' but not have an edge to 's'
(test (let {[$s 1]}
(match-all graph-data1 (graph integer)
[<cons <edge ,s $x>
^<cons <edge ,x ,x>
_>>
x])))
;; find all nodes in two path from 's'
(test (let {[$s 1]}
(match-all graph-data1 (graph integer)
[<cons <edge (& ,s $x_1) $x_2>
<cons <edge ,x_2 $x_3>
_>>
x])))
;; enumerate first 5 paths from 's' to 'e'
(test (take 5 (let {[$s 1] [$e 2]}
(match-all graph-data2 (graph integer)
[<cons <edge (& ,s $x_1) $x_2>
(loop $i [4 $n]
<cons <edge ,x_(- i 2) $x_(- i 1)> ...>
<cons <edge ,x_(- n 1) (& ,e $x_n)> _>)>
x]))))
;; find all cliques whose size is 'n'
(test (let {[$n 3]}
(match-all graph-data2 (graph integer)
[<cons <edge $x_1 $x_2>
(loop $i [3 ,n]
<cons <edge ,x_1 $x_i>
(loop $j [2 ,(- i 1)]
<cons <edge ,x_j ,x_i> ...>
...)
_>
_)>
x])))