Skip to content

Commit 56dedcd

Browse files
xerenhernanponcedeleon
authored andcommitted
Add cat parsing support for recursive sets.
1 parent f367c61 commit 56dedcd

File tree

4 files changed

+96
-10
lines changed

4 files changed

+96
-10
lines changed

dartagnan/src/main/java/com/dat3m/dartagnan/encoding/EncodingContext.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ public EdgeEncoder edge(Relation relation) {
255255
EventGraph must = k.getMustSet();
256256
EdgeEncoder variable = relation.getDefinition().getEdgeVariableEncoder(this);
257257
return (e1, e2) -> {
258+
checkArgument(!relation.isSet() || e1.equals(e2), "Cannot encode pairs of events in an event set");
258259
if (!may.contains(e1, e2)) {
259260
return booleanFormulaManager.makeFalse();
260261
}

dartagnan/src/main/java/com/dat3m/dartagnan/parsers/cat/VisitorCat.java

Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,8 @@ public Void visitLetRecDefinition(LetRecDefinitionContext ctx) {
157157
final int recSize = ctx.letRecAndDefinition().size() + 1;
158158
final Relation[] recursiveGroup = new Relation[recSize];
159159
final String[] lhsNames = new String[recSize];
160-
161-
// Create the recursive relations
160+
final ExpressionContext[] rhsContexts = new ExpressionContext[recSize];
161+
// Recompose the syntax.
162162
for (int i = 0; i < recSize; i++) {
163163
// First relation needs special treatment due to syntactic difference
164164
final String relName = i == 0 ? ctx.n.getText() : ctx.letRecAndDefinition(i - 1).n.getText();
@@ -167,14 +167,18 @@ public Void visitLetRecDefinition(LetRecDefinitionContext ctx) {
167167
throw new MalformedMemoryModelException(errorMsg);
168168
}
169169
lhsNames[i] = relName;
170-
recursiveGroup[i] = wmm.newRelation(createUniqueName(relName));
170+
rhsContexts[i] = i == 0 ? ctx.e : ctx.letRecAndDefinition(i - 1).e;
171+
}
172+
// Create the recursive relations.
173+
for (int i = 0; i < recSize; i++) {
174+
final Relation.Arity arity = rhsContexts[i].accept(new ArityInspector());
175+
recursiveGroup[i] = wmm.newRelation(createUniqueName(lhsNames[i]), arity);
171176
recursiveGroup[i].setRecursive();
172-
namespace.put(relName, recursiveGroup[i]);
177+
namespace.put(lhsNames[i], recursiveGroup[i]);
173178
}
174-
175-
// Parse recursive definitions
179+
// Parse recursive definitions.
176180
for (int i = 0; i < recSize; i++) {
177-
final ExpressionContext rhs = i == 0 ? ctx.e : ctx.letRecAndDefinition(i - 1).e;
181+
final ExpressionContext rhs = rhsContexts[i];
178182
final Relation lhs = recursiveGroup[i];
179183
setRelationToBeDefined(lhs);
180184
final Relation parsedRhs = parseAsRelation(rhs);
@@ -326,15 +330,13 @@ public Relation visitExprTransRef(ExprTransRefContext c) {
326330

327331
@Override
328332
public Relation visitExprDomain(ExprDomainContext c) {
329-
checkNoRecursion(c);
330333
Relation r0 = wmm.newSet();
331334
Relation r1 = parseAsRelation(c.e);
332335
return addDefinition(new Domain(r0, r1));
333336
}
334337

335338
@Override
336339
public Relation visitExprRange(ExprRangeContext c) {
337-
checkNoRecursion(c);
338340
Relation r0 = wmm.newSet();
339341
Relation r1 = parseAsRelation(c.e);
340342
return addDefinition(new Range(r0, r1));
@@ -407,5 +409,69 @@ private static CatParser getParser(CharStream input) {
407409
parser.addErrorListener(new DiagnosticErrorListener(true));
408410
return parser;
409411
}
412+
413+
private final class ArityInspector extends CatBaseVisitor<Relation.Arity> {
414+
415+
private ArityInspector() {}
416+
417+
@Override
418+
public Relation.Arity visitExprBasic(ExprBasicContext c) {
419+
final Object object = namespace.get(c.n.getText());
420+
return object instanceof Relation r ? r.getArity() : null;
421+
}
422+
423+
@Override
424+
public Relation.Arity visitExprDomain(ExprDomainContext c) {
425+
return Relation.Arity.UNARY;
426+
}
427+
428+
@Override
429+
public Relation.Arity visitExprRange(ExprRangeContext c) {
430+
return Relation.Arity.UNARY;
431+
}
432+
433+
@Override
434+
public Relation.Arity visitExprCartesian(ExprCartesianContext c) {
435+
return Relation.Arity.BINARY;
436+
}
437+
438+
@Override
439+
public Relation.Arity visitExprComposition(ExprCompositionContext c) {
440+
return Relation.Arity.BINARY;
441+
}
442+
443+
@Override
444+
public Relation.Arity visitExprIdentity(ExprIdentityContext c) {
445+
return Relation.Arity.BINARY;
446+
}
447+
448+
@Override
449+
public Relation.Arity visitExprUnion(ExprUnionContext c) {
450+
return join(c.e1, c.e2);
451+
}
452+
453+
@Override
454+
public Relation.Arity visitExprIntersection(ExprIntersectionContext c) {
455+
return join(c.e1, c.e2);
456+
}
457+
458+
@Override
459+
public Relation.Arity visitExprMinus(ExprMinusContext c) {
460+
return join(c.e1, c.e2);
461+
}
462+
463+
private Relation.Arity join(ExpressionContext e1, ExpressionContext e2) {
464+
final Relation.Arity k1 = e1.accept(this);
465+
final Relation.Arity k2 = e2.accept(this);
466+
checkCompatible(k1, k2);
467+
return k1 == null ? k2 : k1;
468+
}
469+
470+
private static void checkCompatible(Relation.Arity k1, Relation.Arity k2) {
471+
if (k1 != null && k2 != null && !k1.equals(k2)) {
472+
throw new ParsingException("Incompatible kinds %s and %s".formatted(k1, k2));
473+
}
474+
}
475+
}
410476
}
411477

dartagnan/src/main/java/com/dat3m/dartagnan/solver/caat4wmm/basePredicates/DynamicDefaultWMMSet.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import com.dat3m.dartagnan.wmm.Relation;
88
import com.dat3m.dartagnan.wmm.analysis.RelationAnalysis;
99

10-
// A default implementation for any encoded relation, e.g. base relations or non-base but cut relations.
10+
// A default implementation for any encoded set, e.g. base sets or non-base but cut sets.
1111
public class DynamicDefaultWMMSet extends MaterializedWMMSet {
1212

1313
private final Relation relation;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package com.dat3m.dartagnan.parsers.cat;
2+
3+
import com.dat3m.dartagnan.wmm.Wmm;
4+
import org.junit.Test;
5+
6+
import static org.junit.Assert.assertTrue;
7+
8+
public class CatParserTest {
9+
10+
@Test
11+
public void recursiveSet() {
12+
final String text = """
13+
let rec r0 = domain(loc & ([W]; po; [F]; po; [R])) | domain([r0]; addr)
14+
acyclic (po & loc) | addr | data | ctrl | rf | co | fr | po ; [r0]
15+
""";
16+
final Wmm memoryModel = new ParserCat().parse(text);
17+
assertTrue(memoryModel.getRelation("r0").isRecursive());
18+
}
19+
}

0 commit comments

Comments
 (0)