Skip to content

Commit d826012

Browse files
authored
Merge pull request #12 from mthom/naf_heuristic_schemaless_checking
augment SchemalessChecker with possible-Naf-floundering notifications and add systematic plus exploratory tests
2 parents 9998ae4 + da29c06 commit d826012

40 files changed

+1028
-3
lines changed

PSOACore/src/main/antlr3/org/ruleml/psoa/analyzer/SchemalessChecker.g

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

103107
rule
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

177188
naf_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

199248
term
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

Comments
 (0)