# MATH introduce graph structures
[hear] (define make-graph /
         lambda (nodes links) (pair (nodes) (links)));

[hear] (define test-graph /
         make-graph
          (vector 1 2 3 4)
          (vector (vector 1 2) (vector 2 3) (vector 1 4)));

[hear] (define graph-linked /
         lambda (g n1 n2)
          (exists /
           ? idx /
           if (and (>= (idx) 0)
                   (< (idx) (list-length / list-ref (g) 1)))
            (list= (list-ref (list-ref (g) 1) (idx))
                   (vector (n1) (n2)))
            (false)));

[hear] (= (graph-linked (test-graph) 1 2) (true));

[hear] (= (graph-linked (test-graph) 1 3) (false));

[hear] (= (graph-linked (test-graph) 2 4) (false));

       # 'if' is used a lot in the next definition in place of and / or
       # this is because I haven't established lazy evaluation forms for and / or
       # so this very inefficient algorithm completely bogs down when combined
       # ... during testing with a dumb implementation for 'exists'.
[hear] (define graph-linked* /
         lambda (g n1 n2)
          (if (= (n1) (n2))
            (true)
            (if (graph-linked (g) (n1) (n2))
              (true)
              (exists
                (? n3 /
                 if (graph-linked (g) (n1) (n3))
                  (graph-linked* (g) (n3) (n2))
                  (false))))));

[hear] (= (graph-linked* (test-graph) 1 2) (true));

[hear] (= (graph-linked* (test-graph) 1 3) (true));

[hear] (= (graph-linked* (test-graph) 2 4) (false));