abstract sig City {roads: Int->City}
one sig A,B,C,D,E,F,G,H,I,J
  extends City {}
fact fixed {
  let onedirection =
    A->4->D + D->5->I + A->6->B + B->4->C + A->3->C +
    B->3->E + C->5->D + C->2->E + E->6->F + E->5->G +
    D->2->H + D->3->F + F->4->G + F->2->H + H->2->I +
    G->3->J + H->5->J + I->4->J | {
  roads = onedirection +
          {a: City, w: Int, b: City | b->w->a in onedirection}
  }
}
run {} for 10 City, 5 int
// Note: sentinel value, beware!
// Note also: if we allowed multiple edges
//   of different weights between the same cities,
//   this would break!
fun w[a, b: City]: Int {
  some roads[a].b => roads[a].b else -1
}
fun weighta[es: City -> Int -> City]: Int {
  sum w : es[City].City | w // drops values
}
fun weightb[es: City -> Int -> City]: Int {
  sum a: es[City][Int], b: es.City.Int | es[a].b
}