;;;
;;;
;;; Bipartite Graph demonstartion
;;;
;;;

;;
;; Matcher definitions
;;
(define $bipartite-graph
  (lambda [$a $b]
    (multiset (edge a b))))

(define $edge
  (lambda [$a $b]
    (algebraic-data-matcher
      {<edge a b>})))

;;
;; Demonstration code
;;
(define $bipartite-graph-data
  {<Edge 1 "a">
   <Edge 1 "a">
   <Edge 1 "a">
   <Edge 1 "a">
   <Edge 1 "b">
   <Edge 1 "c">
   <Edge 2 "a">
   <Edge 2 "a">
   <Edge 2 "a">
   <Edge 2 "a">
   <Edge 2 "a">
   <Edge 3 "c">
   <Edge 4 "a">
   <Edge 5 "a">
   <Edge 5 "b">
   <Edge 5 "c">
   <Edge 6 "c">
   <Edge 6 "c">
   <Edge 6 "c">
   })

(test (match-all bipartite-graph-data (bipartite-graph integer string)
        [<cons <edge ,1 $str> _> str]))

(test (unique/m integer
                (match-all bipartite-graph-data (bipartite-graph integer string)
                  [<cons <edge $n $str>
                         <cons <edge ,n ,str>
                               !<cons <edge ,n !,str> _>>>
                   n])))

(test (unique/m integer
                (match-all bipartite-graph-data (bipartite-graph integer string)
                  [<cons <edge $n $str>
                         <cons <edge ,n ,str>
                               !<cons <edge ,n !,str> _>>>
                   n])))

(test (unique/m integer
                (match-all bipartite-graph-data (bipartite-graph integer string)
                  [<cons <edge $n ,"a"> _>
                   n])))

(test (unique/m integer
                (match-all bipartite-graph-data (bipartite-graph integer string)
                  [<cons <edge $n ,"a">
                    <cons <edge ,n ,"c">
                     _>>
                   n])))

;; I found bug on nested not-patterns
;(test (unique/m integer
;                (match-all bipartite-graph-data (bipartite-graph integer string)
;                  [(& <cons <edge $n $str>
;                            <cons <edge ,n ,str>
;                                  <cons <edge ,n ,str> _>>>
;                      !<cons <edge $n2 $str2>
;                             !<cons <edge ,n2 ,str2> _>>)
;                   n])))

(test (unique/m integer
                (match-all bipartite-graph-data (bipartite-graph integer string)
                  [<cons <edge $n2 $str2>
                         !<cons <edge ,n2 ,str2> _>>
                  n2])))