open util/ternary
  sig Atom {}
  -----------------------------
  -- Plug in your own isUndirectedTree
  --  and spans predicates here.
  pred isUndirectedTree[r: Atom -> Atom] {
    // FILL
  }
  pred spans[graph1, graph2: Atom -> Atom] {
    // FILL
  }
  pred spanningTree[tree, graph2: Atom -> Atom] {
    spans[tree, graph2]
    isUndirectedTree[tree]
  }
  run spanningTree for exactly 5 Atom, 8 int
  ----------------------------------------------
  pred properWeights[g: Atom -> Int -> Atom] {
    all a1, a2: Atom | lone i : Int | a1->i->a2 in g
    all i : Atom.g.Atom | i > 0 and i < 11
    all a1, a2: Atom | a1.g.a2 = a2.g.a1 -- symmetric
    -- 2 alternates! Try them out...
    -- select13[g] = ~select13[g] -- TODO: try in evaluator
    --let myTranspose = {a2: Atom, i: Int, a1: Atom | a1->i->a2 in g} |
    --  myTranspose = g
  }
  fun weight[g: Atom -> Int -> Atom]: Int {
    let s = (sum a: Atom |
              sum b: Atom |
                a.g.b) |
                  div[s, 2]
  }
  pred minSpanningTree[tree, wgraph: Atom -> Int -> Atom] {
     -- unweighted version: select13[tree]
    spanningTree[select13[tree], select13[wgraph]]
    tree in wgraph
    properWeights[wgraph]

    all tree2: /*set*/ Atom -> Int -> Atom | {
      (spanningTree[select13[tree2], select13[wgraph]] and tree2 in wgraph)
     implies (weight[tree2] >= weight[tree])
    }
  }
  run minSpanningTree for exactly 5 Atom, 8 int