-
Notifications
You must be signed in to change notification settings - Fork 2
/
expansion-list.js
executable file
·61 lines (49 loc) · 1.82 KB
/
expansion-list.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
import fs from "fs"
import { pgformat } from "pgraphs"
const pg = process.argv.slice(2).map(file => fs.readFileSync(file).toString()).join("\n")
const { nodes, edges } = pgformat.pg.parse(pg)
nodes.forEach(n => n.id = n.id.replaceAll("-","_"))
edges.forEach(e => { e.from = e.from.replaceAll("-","_"); e.to = e.to.replaceAll("-","_") })
const broader = {}
const isBroader = (from, to) => {
if (!from || !to) return
from in broader
? broader[from].add(to)
: broader[from] = new Set([to])
broader[to] ||= new Set()
}
const crmId = id => {
const match = id.match(/^([EP][0-9]+)_/)
return match ? match[1] : null
}
for (let { from, to, labels } of edges) {
if (labels.find(l => l == "replacedBy" || l == "superClass" || l == "superProperty")) {
to = crmId(to) || to
isBroader(from, to)
isBroader(crmId(from), to)
}
}
for (let { id, properties } of nodes) {
if (properties.alias) // e.g. E22_Man_Made_Object => E22
isBroader(properties.alias[0], crmId(id) || id)
isBroader(id, crmId(id)) // e.g. E52_Time_Span => E52
}
// calculation of transitive closure
const names = Object.keys(broader).sort() // id => name
const ids = Object.fromEntries(names.map((name,i) => [name,i])) // name => id
const reach = Array.from(Array(names.length), () => names.map(() => false))
for (let from in broader)
for (let to of broader[from])
reach[ids[from]][ids[to]] = true
for (let k=0; k<names.length; k++)
for (let i=0; i<names.length; i++)
for (let j=0; j<names.length; j++)
reach[i][j] ||= (reach[i][k] && reach[k][j])
// emit result
for (let i=0; i<names.length; i++) {
const from = names[i]
if (from.match(/^E\d+$/)) continue // these are not used directly
const to = names.filter((name,j) => i!=j && reach[i][j])
if (to.length)
console.log([from, ...to].join(" "))
}