/** * @param rules set of rules of interest forming a rule subgraph * @return true if the rule subgraph formed from provided rules contains loops */ public static boolean subGraphIsCyclical(Set<InferenceRule> rules){ Iterator<Rule> ruleIterator = rules.stream() .map(InferenceRule::getRule) .iterator(); boolean cyclical = false; while (ruleIterator.hasNext() && !cyclical){ Set<Rule> visitedRules = new HashSet<>(); Stack<Rule> rulesToVisit = new Stack<>(); rulesToVisit.push(ruleIterator.next()); while(!rulesToVisit.isEmpty() && !cyclical) { Rule rule = rulesToVisit.pop(); if (!visitedRules.contains(rule)){ rule.thenTypes() .flatMap(SchemaConcept::whenRules) .forEach(rulesToVisit::add); visitedRules.add(rule); } else { cyclical = true; } } } return cyclical; }