sclass ConceptsRefChecker { Concepts cc; new L errors; sclass Err {} srecord ErrNoBackRef(Concept.Ref ref, Concept dest) > Err {} srecord ErrSuperfluousBackRef(Concept.Ref ref, Concept dest) > Err {} // a reference from a concept that is not in the concepts list srecord ErrDanglingSource(Concept.Ref ref, Concept dest) > Err {} // a reference to a concept that is not in the concepts list srecord ErrDanglingDestination(Concept.Ref ref, Concept dest) > Err {} *() {} *(Concepts *cc) {} L run() { errors.clear(); if (cc == null) ret errors; for (Concept c : cc.allConcepts()) { for (Concept.Ref ref : c.backRefs) { if (ref! != c) errors.add(new ErrSuperfluousBackRef(ref, c)); if (ref.concept()._concepts != cc) errors.add(new ErrDanglingSource(ref, c)); } for (Concept.Ref ref : c.refs) if (ref.has()) { if (!contains(ref->backRefs, ref)) errors.add(new ErrNoBackRef(ref, c)); if (ref->_concepts != cc) errors.add(new ErrDanglingDestination(ref, c)); } } ret errors; } L errors() { ret errors; } }