sortResult sorts the strata topologically (ignoring cycles).
(strata []Nodeset, predToStratumMap map[ast.PredicateSym]int)
| 181 | |
| 182 | // sortResult sorts the strata topologically (ignoring cycles). |
| 183 | func (dep depGraph) sortResult(strata []Nodeset, predToStratumMap map[ast.PredicateSym]int) ([]Nodeset, map[ast.PredicateSym]int) { |
| 184 | var sorted []int |
| 185 | seen := make(map[int]struct{}) |
| 186 | var visitStratum func(index int) |
| 187 | visitStratum = func(index int) { |
| 188 | if _, ok := seen[index]; ok { |
| 189 | return |
| 190 | } |
| 191 | seen[index] = struct{}{} |
| 192 | for sym := range strata[index] { |
| 193 | for d := range dep[sym] { |
| 194 | visitStratum(predToStratumMap[d]) |
| 195 | } |
| 196 | } |
| 197 | sorted = append(sorted, index) |
| 198 | } |
| 199 | |
| 200 | for i := 0; i < len(strata); i++ { |
| 201 | visitStratum(i) |
| 202 | } |
| 203 | newstrata := make([]Nodeset, len(strata), len(strata)) |
| 204 | oldToNew := make(map[int]int) |
| 205 | for i := 0; i < len(strata); i++ { |
| 206 | newstrata[i] = strata[sorted[i]] |
| 207 | oldToNew[sorted[i]] = i |
| 208 | } |
| 209 | newPredToStratumMap := make(map[ast.PredicateSym]int, len(predToStratumMap)) |
| 210 | for sym := range predToStratumMap { |
| 211 | newPredToStratumMap[sym] = oldToNew[predToStratumMap[sym]] |
| 212 | } |
| 213 | return newstrata, newPredToStratumMap |
| 214 | } |