@Override public void visit(Sentence node) { inCondition = false; left.clear(); right.clear(); fresh.clear(); current = left; node.getBody().accept(this); if (node.getRequires() != null) { current = right; inCondition = true; node.getRequires().accept(this); } // TODO: add checks for Ensures, too. for (Variable v : right.keySet()) { if (MetaK.isAnonVar(v) && !v.isFresh()) { GlobalSettings.kem.register( new KException( KException.ExceptionType.ERROR, KException.KExceptionGroup.COMPILER, "Anonymous variable found in the right hand side of a rewrite.", getName(), v.getFilename(), v.getLocation())); } if (!left.containsKey(v)) { node.addAttribute(UNBOUNDED_VARS, ""); /* matching logic relaxes this restriction */ if (!GlobalSettings.javaBackend) { GlobalSettings.kem.register( new KException( KException.ExceptionType.ERROR, KException.KExceptionGroup.COMPILER, "Unbounded Variable " + v.toString() + ".", getName(), v.getFilename(), v.getLocation())); } else { GlobalSettings.kem.register( new KException( KException.ExceptionType.WARNING, KException.KExceptionGroup.COMPILER, "Unbounded Variable " + v.toString() + ".", getName(), v.getFilename(), v.getLocation())); } } } for (Map.Entry<Variable, Integer> e : left.entrySet()) { final Variable key = e.getKey(); if (fresh.containsKey(key)) { GlobalSettings.kem.register( new KException( KException.ExceptionType.ERROR, KException.KExceptionGroup.COMPILER, "Variable " + key + " has the same name as a fresh " + "variable.", getName(), key.getFilename(), key.getLocation())); } if (MetaK.isAnonVar(key)) continue; if (e.getValue().intValue() > 1) continue; if (!right.containsKey(key)) { GlobalSettings.kem.register( new KException( KException.ExceptionType.HIDDENWARNING, KException.KExceptionGroup.COMPILER, "Singleton variable " + key.toString() + ".\n" + " If this is not a spelling mistake, please consider using anonymous variables.", getName(), key.getFilename(), key.getLocation())); } } }