@@ -41,7 +41,11 @@ options
4141 private boolean m_forallWrap;
4242
4343 private Set< String> m_freeVars = new HashSet< String> ();
44- private Set< String> m_quantifiedVars = new HashSet< String> ();
44+ private Set< String> m_quantifiedVars = new HashSet< String> ();
45+ private Set< String> m_nonNafVars = new HashSet< String> ();
46+ private Set< String> m_headVars = new HashSet< String> ();
47+
48+ private int m_nafLevels = 0 ;
4549
4650 private void recordExistentialVar(Set< String> existVars, String v) {
4751 if (!m_quantifiedVars.contains(v)) {
@@ -101,12 +105,19 @@ query
101105 ;
102106
103107rule
108+ scope
109+ {
110+ String text;
111+ }
104112@init
105113{
114+ $rule:: text = $rule.text;
106115 m_hasForall = false ;
107116
117+ m_nonNafVars.clear();
108118 m_quantifiedVars.clear();
109119 m_freeVars.clear();
120+ m_headVars.clear();
110121}
111122@after
112123{
@@ -175,6 +186,44 @@ scope {
175186 ;
176187
177188naf_formula
189+ scope
190+ {
191+ Set< String> nafVars;
192+ boolean containsAnonymousVariables;
193+ }
194+ @init
195+ {
196+ ++ m_nafLevels;
197+ $naf_formula:: nafVars = new HashSet< String> ();
198+ $naf_formula:: containsAnonymousVariables = false ;
199+ }
200+ @after
201+ {
202+ -- m_nafLevels;
203+
204+ HashSet< String> headNafVars = new HashSet(m_headVars);
205+ headNafVars.retainAll($naf_formula:: nafVars);
206+
207+ if (!m_nonNafVars.containsAll(headNafVars)) {
208+ headNafVars.removeAll(m_nonNafVars);
209+ printErrln(" Warning: Conclusion variable(s): ?" + String.join(" , ?" , headNafVars) + " \n " +
210+ " do(es) not occur in a conjunct preceding the Naf, which should be instantiated " +
211+ " to prevent floundering: \n " + $rule:: text + " \n " );
212+ }
213+
214+ $naf_formula:: nafVars.removeAll(m_nonNafVars);
215+ $naf_formula:: nafVars.removeAll(m_headVars);
216+
217+ if (!$naf_formula:: nafVars.isEmpty()) {
218+ printErrln(" Finding: Variable(s): ?" + String.join(" , ?" , $naf_formula:: nafVars) + " \n " +
219+ " do(es) not occur in a conjunct preceding the Naf: \n " + $rule:: text + " \n " );
220+ }
221+
222+ if ($naf_formula:: containsAnonymousVariables) {
223+ printErrln(" Finding: A Naf in the rule: \n " + $rule:: text + " \n " +
224+ " contains an anonymous variable.\n " );
225+ }
226+ }
178227 : ^ (NAF formula)
179228 ;
180229
@@ -198,7 +247,20 @@ subclass
198247
199248term
200249 : constant
201- | VAR_ID { if (!$VAR_ID.text.isEmpty() && !m_quantifiedVars.contains($VAR_ID.text)) m_freeVars.add($VAR_ID.text); }
250+ | VAR_ID
251+ { if (!$VAR_ID.text.isEmpty() && !m_quantifiedVars.contains($VAR_ID.text))
252+ m_freeVars.add($VAR_ID.text);
253+
254+ if (m_nafLevels > 0 )
255+ if ($VAR_ID.text.isEmpty())
256+ $naf_formula:: containsAnonymousVariables = true ;
257+ else
258+ $naf_formula:: nafVars.add($VAR_ID.text);
259+ else if (m_isRuleBody) // Non- empty difference of Naf variables with union of head and pre- Naf- condition variables
260+ m_nonNafVars.add($VAR_ID.text);
261+ else
262+ m_headVars.add($VAR_ID.text);
263+ }
202264 | psoa
203265 | external
204266 ;
0 commit comments