Skip to content

Commit 60b819f

Browse files
committed
Evolog Modules: Revert to single-predicate module input
1 parent 761331c commit 60b819f

File tree

7 files changed

+103
-69
lines changed

7 files changed

+103
-69
lines changed

alpha-api/src/main/java/at/ac/tuwien/kr/alpha/api/programs/modules/Module.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ public interface Module {
99

1010
String getName();
1111

12-
Set<Predicate> getInputSpec();
12+
Predicate getInputSpec();
1313

1414
Set<Predicate> getOutputSpec();
1515

alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/ModuleImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
class ModuleImpl implements Module {
1010

1111
private final String name;
12-
private final Set<Predicate> inputSpec;
12+
private final Predicate inputSpec;
1313
private final Set<Predicate> outputSpec;
1414
private final InputProgram implementation;
1515

16-
ModuleImpl(String name, Set<Predicate> inputSpec, Set<Predicate> outputSpec, InputProgram implementation) {
16+
ModuleImpl(String name, Predicate inputSpec, Set<Predicate> outputSpec, InputProgram implementation) {
1717
this.name = name;
1818
this.inputSpec = inputSpec;
1919
this.outputSpec = outputSpec;
@@ -26,7 +26,7 @@ public String getName() {
2626
}
2727

2828
@Override
29-
public Set<Predicate> getInputSpec() {
29+
public Predicate getInputSpec() {
3030
return this.inputSpec;
3131
}
3232

alpha-commons/src/main/java/at/ac/tuwien/kr/alpha/commons/programs/modules/Modules.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ private Modules() {
1212
throw new AssertionError("Cannot instantiate utility class!");
1313
}
1414

15-
public static Module newModule(final String name, final Set<Predicate> inputSpec, final Set<Predicate> outputSpec, final InputProgram implementation) {
15+
public static Module newModule(final String name, final Predicate inputSpec, final Set<Predicate> outputSpec, final InputProgram implementation) {
1616
return new ModuleImpl(name, inputSpec, outputSpec, implementation);
1717
}
1818

alpha-core/src/main/antlr/at/ac/tuwien/kr/alpha/core/antlr/ASPCore2.g4

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,5 +121,5 @@ test_assert_all : TEST_ASSERT_ALL CURLY_OPEN statements? CURLY_CLOSE;
121121

122122
test_assert_some : TEST_ASSERT_SOME CURLY_OPEN statements? CURLY_CLOSE;
123123

124-
module_signature : CURLY_OPEN predicate_specs? CURLY_CLOSE ARROW CURLY_OPEN ('*' | predicate_specs) CURLY_CLOSE;
124+
module_signature : predicate_spec ARROW CURLY_OPEN ('*' | predicate_specs) CURLY_CLOSE;
125125

alpha-core/src/main/java/at/ac/tuwien/kr/alpha/core/parser/ParseTreeVisitor.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -335,18 +335,18 @@ public Object visitDirective_module(ASPCore2Parser.Directive_moduleContext ctx)
335335
}
336336
// directive_module: SHARP DIRECTIVE_MODULE id PAREN_OPEN module_signature PAREN_CLOSE CURLY_OPEN statements CURLY_CLOSE;
337337
String name = visitId(ctx.id());
338-
ImmutablePair<Set<Predicate>, Set<Predicate>> moduleSignature = visitModule_signature(ctx.module_signature());
338+
ImmutablePair<Predicate, Set<Predicate>> moduleSignature = visitModule_signature(ctx.module_signature());
339339
startNestedProgram();
340340
visitStatements(ctx.statements());
341341
InputProgram moduleImplementation = endNestedProgram();
342342
currentLevelProgramBuilder.addModule(Modules.newModule(name, moduleSignature.getLeft(), moduleSignature.getRight(), moduleImplementation));
343343
return null;
344344
}
345345

346-
public ImmutablePair<Set<Predicate>, Set<Predicate>> visitModule_signature(ASPCore2Parser.Module_signatureContext ctx) {
347-
Set<Predicate> inputPredicates = ctx.predicate_specs(0) != null ? visitPredicate_specs(ctx.predicate_specs(0)) : Collections.emptySet();
348-
Set<Predicate> outputPredicates = ctx.predicate_specs(1) != null ? visitPredicate_specs(ctx.predicate_specs(1)) : Collections.emptySet();
349-
return ImmutablePair.of(inputPredicates, outputPredicates);
346+
public ImmutablePair<Predicate, Set<Predicate>> visitModule_signature(ASPCore2Parser.Module_signatureContext ctx) {
347+
Predicate inputPredicate = visitPredicate_spec(ctx.predicate_spec());
348+
Set<Predicate> outputPredicates = ctx.predicate_specs() != null ? visitPredicate_specs(ctx.predicate_specs()) : Collections.emptySet();
349+
return ImmutablePair.of(inputPredicate, outputPredicates);
350350
}
351351

352352
@Override
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package at.ac.tuwien.kr.alpha.core.programs.transformation;
2+
3+
import at.ac.tuwien.kr.alpha.api.Alpha;
4+
import at.ac.tuwien.kr.alpha.api.programs.NormalProgram;
5+
import at.ac.tuwien.kr.alpha.api.programs.atoms.ExternalAtom;
6+
import at.ac.tuwien.kr.alpha.api.programs.atoms.ModuleAtom;
7+
import at.ac.tuwien.kr.alpha.api.programs.literals.Literal;
8+
import at.ac.tuwien.kr.alpha.api.programs.literals.ModuleLiteral;
9+
import at.ac.tuwien.kr.alpha.api.programs.modules.Module;
10+
import at.ac.tuwien.kr.alpha.api.programs.rules.NormalRule;
11+
import at.ac.tuwien.kr.alpha.api.programs.rules.heads.NormalHead;
12+
import at.ac.tuwien.kr.alpha.commons.programs.rules.Rules;
13+
14+
import java.util.List;
15+
import java.util.Map;
16+
import java.util.Set;
17+
import java.util.function.Function;
18+
import java.util.stream.Collectors;
19+
20+
/**
21+
* Program transformation that translates {@link at.ac.tuwien.kr.alpha.api.programs.literals.ModuleLiteral}s into
22+
* {@link at.ac.tuwien.kr.alpha.api.programs.literals.ExternalLiteral}s by constructing {@link at.ac.tuwien.kr.alpha.api.programs.atoms.ExternalAtom}s
23+
* which solve the ASP implementation of the module with the given inputs.
24+
*/
25+
public class ModuleLinker extends ProgramTransformation<NormalProgram, NormalProgram> {
26+
27+
// Note: References to a standard library of modules that are always available for linking should be member variables of a linker.
28+
29+
private final Alpha moduleRunner;
30+
31+
public ModuleLinker(Alpha moduleRunner) {
32+
this.moduleRunner = moduleRunner;
33+
}
34+
35+
36+
@Override
37+
public NormalProgram apply(NormalProgram inputProgram) {
38+
Map<String, Module> moduleTable = inputProgram.getModules().stream().collect(Collectors.toMap(Module::getName, Function.identity()));
39+
List<NormalRule> transformedRules = inputProgram.getRules().stream()
40+
.map(rule -> containsModuleAtom(rule) ? linkModuleAtoms(rule, moduleTable) : rule)
41+
.collect(Collectors.toList());
42+
return null;
43+
}
44+
45+
private NormalRule linkModuleAtoms(NormalRule rule, Map<String, Module> moduleTable) {
46+
NormalHead newHead = rule.getHead();
47+
Set<Literal> newBody = rule.getBody().stream()
48+
.map(literal -> {
49+
if (literal instanceof ModuleLiteral) {
50+
ModuleLiteral moduleLiteral = (ModuleLiteral) literal;
51+
return translateModuleAtom(moduleLiteral.getAtom(), moduleTable).toLiteral(!moduleLiteral.isNegated());
52+
} else {
53+
return literal;
54+
}
55+
})
56+
.collect(Collectors.toSet());
57+
return Rules.newNormalRule(newHead, newBody);
58+
}
59+
60+
private ExternalAtom translateModuleAtom(ModuleAtom moduleAtom, Map<String, Module> moduleTable) {
61+
if (!moduleTable.containsKey(moduleAtom.getModuleName())) {
62+
throw new IllegalArgumentException("Module " + moduleAtom.getModuleName() + " not found in module table.");
63+
}
64+
Module implementationModule = moduleTable.get(moduleAtom.getModuleName());
65+
//implementationModule.
66+
return null;
67+
}
68+
69+
private static boolean containsModuleAtom(NormalRule rule) {
70+
return rule.getBody().stream().anyMatch(literal -> literal instanceof ModuleLiteral);
71+
}
72+
73+
}

alpha-core/src/test/java/at/ac/tuwien/kr/alpha/core/parser/ParserTest.java

Lines changed: 19 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,10 @@ public class ParserTest {
6969

7070
private static final String UNIT_TEST_EXPECT_UNSAT =
7171
"p(1). p(2). "
72-
+ ":- p(X), p(Y), X + Y = 3."
73-
+ "#test expected_unsat(expect: unsat) {"
74-
+ "given {}"
75-
+ "}";
72+
+ ":- p(X), p(Y), X + Y = 3."
73+
+ "#test expected_unsat(expect: unsat) {"
74+
+ "given {}"
75+
+ "}";
7676

7777
private static final String UNIT_TEST_BASIC_TEST =
7878
"a :- b. #test ensure_a(expect: 1) { given { b. } assertForAll { :- not a. } }";
@@ -86,17 +86,13 @@ public class ParserTest {
8686
private static final String UNIT_TEST_KEYWORDS_AS_IDS =
8787
"assert(a) :- given(b). # test test(expect: 1) { given { given(b). } assertForAll { :- not assert(a). :- assertForSome(b).}}";
8888

89-
private static final String MODULE_SIMPLE = "#module aSimpleModule({input/1} => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }";
89+
private static final String MODULE_SIMPLE = "#module aSimpleModule(input/1 => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }";
9090

91-
private static final String MODULE_OUTPUT_ALL = "#module mod({in/1} => {*}) { a(X). b(X) :- a(X).}";
91+
private static final String MODULE_OUTPUT_ALL = "#module mod(in/1 => {*}) { a(X). b(X) :- a(X).}";
9292

93-
private static final String MODULE_WITH_REGULAR_STMTS = "p(a). p(b). q(X) :- p(X). #module aSimpleModule({input/1} => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }";
93+
private static final String MODULE_WITH_REGULAR_STMTS = "p(a). p(b). q(X) :- p(X). #module aSimpleModule(input/1 => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }";
9494

95-
private static final String MODULE_MULTIPLE_DEFINITIONS = "a. b(5). #module aSimpleModule({input/1} => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). } q(Y) :- r(S, Y), t(S). #module anotherModule({input/1} => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }";
96-
97-
private static final String MODULE_EMPTY_INPUT_SPEC = "#module someModule({} => {*}) {p(a).}";
98-
99-
private static final String MODULE_MULTIPLE_INPUTS = "#module someModule({input/1, input2/2} => {out1/2}) {p(a).}";
95+
private static final String MODULE_MULTIPLE_DEFINITIONS = "a. b(5). #module aSimpleModule(input/1 => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). } q(Y) :- r(S, Y), t(S). #module anotherModule(input/1 => {out1/2, out2/3}) { p(a). p(b). q(X) :- p(X). }";
10096

10197
private static final String MODULE_LITERAL = "p(a). q(b). r(X) :- p(X), q(Y), #mod[X, Y](X).";
10298

@@ -336,11 +332,9 @@ public void simpleModule() {
336332
assertEquals(1, modules.size());
337333
Module module = modules.get(0);
338334
assertEquals("aSimpleModule", module.getName());
339-
Set<Predicate> inputSpec = module.getInputSpec();
340-
assertEquals(1, inputSpec.size());
341-
Predicate inputPredicate = inputSpec.iterator().next();
342-
assertEquals("input", inputPredicate.getName());
343-
assertEquals(1, inputPredicate.getArity());
335+
Predicate inputSpec = module.getInputSpec();
336+
assertEquals("input", inputSpec.getName());
337+
assertEquals(1, inputSpec.getArity());
344338
Set<Predicate> outputSpec = module.getOutputSpec();
345339
assertEquals(2, outputSpec.size());
346340
assertTrue(outputSpec.contains(Predicates.getPredicate("out1", 2)));
@@ -358,11 +352,9 @@ public void moduleOutputAll() {
358352
assertEquals(1, modules.size());
359353
Module module = modules.get(0);
360354
assertEquals("mod", module.getName());
361-
Set<Predicate> inputSpec = module.getInputSpec();
362-
assertEquals(1, inputSpec.size());
363-
Predicate inputPredicate = inputSpec.iterator().next();
364-
assertEquals("in", inputPredicate.getName());
365-
assertEquals(1, inputPredicate.getArity());
355+
Predicate inputSpec = module.getInputSpec();
356+
assertEquals("in", inputSpec.getName());
357+
assertEquals(1, inputSpec.getArity());
366358
assertTrue(module.getOutputSpec().isEmpty());
367359
InputProgram implementation = module.getImplementation();
368360
assertEquals(1, implementation.getFacts().size());
@@ -379,11 +371,9 @@ public void moduleAndRegularStmts() {
379371
assertEquals(1, modules.size());
380372
Module module = modules.get(0);
381373
assertEquals("aSimpleModule", module.getName());
382-
Set<Predicate> inputSpec = module.getInputSpec();
383-
assertEquals(1, inputSpec.size());
384-
Predicate inputPredicate = inputSpec.iterator().next();
385-
assertEquals("input", inputPredicate.getName());
386-
assertEquals(1, inputPredicate.getArity());
374+
Predicate inputSpec = module.getInputSpec();
375+
assertEquals("input", inputSpec.getName());
376+
assertEquals(1, inputSpec.getArity());
387377
Set<Predicate> outputSpec = module.getOutputSpec();
388378
assertEquals(2, outputSpec.size());
389379
assertTrue(outputSpec.contains(Predicates.getPredicate("out1", 2)));
@@ -407,42 +397,13 @@ public void multipleModuleDefinitions() {
407397
@Test
408398
public void invalidNestedModule() {
409399
assertThrows(IllegalStateException.class, () ->
410-
parser.parse("#module aSimpleModule({input/1} => {out1/2, out2/3}) { p(a). p(b). #module anotherModule({input/1} => {out1/2, out2/3}) { p(a). p(b). } }"));
400+
parser.parse("#module aSimpleModule(input/1 => {out1/2, out2/3}) { p(a). p(b). #module anotherModule(input/1 => {out1/2, out2/3}) { p(a). p(b). } }"));
411401
}
412402

413403
@Test
414404
public void invalidNestedTest() {
415405
assertThrows(IllegalStateException.class, () ->
416-
parser.parse("#module mod({foo/1} => {*}) { #test test(expect: 1) { given { b. } assertForAll { :- a. } } }"));
417-
}
418-
419-
@Test
420-
public void emptyInputSpec() {
421-
InputProgram prog = parser.parse(MODULE_EMPTY_INPUT_SPEC);
422-
List<Module> modules = prog.getModules();
423-
assertEquals(1, modules.size());
424-
Module module = modules.get(0);
425-
assertEquals("someModule", module.getName());
426-
Set<Predicate> inputSpec = module.getInputSpec();
427-
assertTrue(inputSpec.isEmpty());
428-
Set<Predicate> outputSpec = module.getOutputSpec();
429-
assertTrue(outputSpec.isEmpty());
430-
}
431-
432-
@Test
433-
public void multipleInputs() {
434-
InputProgram prog = parser.parse(MODULE_MULTIPLE_INPUTS);
435-
List<Module> modules = prog.getModules();
436-
assertEquals(1, modules.size());
437-
Module module = modules.get(0);
438-
assertEquals("someModule", module.getName());
439-
Set<Predicate> inputSpec = module.getInputSpec();
440-
assertEquals(2, inputSpec.size());
441-
assertTrue(inputSpec.contains(Predicates.getPredicate("input", 1)));
442-
assertTrue(inputSpec.contains(Predicates.getPredicate("input2", 2)));
443-
Set<Predicate> outputSpec = module.getOutputSpec();
444-
assertEquals(1, outputSpec.size());
445-
assertTrue(outputSpec.contains(Predicates.getPredicate("out1", 2)));
406+
parser.parse("#module mod(foo/1 => {*}) { #test test(expect: 1) { given { b. } assertForAll { :- a. } } }"));
446407
}
447408

448409
@Test

0 commit comments

Comments
 (0)