, \"?x\", \"?x \") .");
+ interpreter.runCommand(command);
+ List facts = interpreter.getKnowledgeBase().getFacts();
+ List rules = interpreter.getKnowledgeBase().getRules();
+ List dataSourceDeclarations = interpreter.getKnowledgeBase().getDataSourceDeclarations();
+
+ assertEquals("addsource", command.getName());
+ assertEquals(2, command.getArguments().size());
+ assertTrue(command.getArguments().get(0).fromTerm().isPresent());
+ assertTrue(command.getArguments().get(1).fromPositiveLiteral().isPresent());
+
+ assertTrue(facts.isEmpty());
+ assertTrue(rules.isEmpty());
+ assertEquals(1, dataSourceDeclarations.size());
+ assertTrue(dataSourceDeclarations.get(0).getDataSource() instanceof SparqlQueryResultDataSource);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongFirstArgumentType_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@addsource \"string\" p(a).");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongSecondArgumentType_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@addsource p[1]: \"string\" .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongSecondArgumentUnknownSource_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@addsource p[1]: unknown(a) .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongSecondArgumentWrongAritySource_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@addsource p[1]: load-rdf(\"file.nt\") .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentCount_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@addsource p[2]: p(a) p(b) .");
+ interpreter.runCommand(command);
+ }
+
+ @Test
+ public void help_succeeds() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ CommandInterpreter commandInterpreter = new AddSourceCommandInterpreter();
+ InterpreterTest.checkHelpFormat(commandInterpreter, interpreter, writer);
+ }
+
+ @Test
+ public void synopsis_succeeds() throws ParsingException, CommandExecutionException {
+ CommandInterpreter commandInterpreter = new AddSourceCommandInterpreter();
+ InterpreterTest.checkSynopsisFormat(commandInterpreter);
+ }
+
+}
diff --git a/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/AssertCommandInterpreterTest.java b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/AssertCommandInterpreterTest.java
new file mode 100644
index 000000000..0d6f01a78
--- /dev/null
+++ b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/AssertCommandInterpreterTest.java
@@ -0,0 +1,95 @@
+package org.semanticweb.rulewerk.commands;
+
+/*-
+ * #%L
+ * Rulewerk command execution support
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import static org.junit.Assert.*;
+
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+import org.semanticweb.rulewerk.core.model.api.Command;
+import org.semanticweb.rulewerk.core.model.api.DataSourceDeclaration;
+import org.semanticweb.rulewerk.core.model.api.Fact;
+import org.semanticweb.rulewerk.core.model.api.Literal;
+import org.semanticweb.rulewerk.core.model.api.Rule;
+import org.semanticweb.rulewerk.parser.ParsingException;
+
+public class AssertCommandInterpreterTest {
+
+ @Test
+ public void correctUse_succeeds() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@assert p(a) q(?X) :- r(?X) .");
+ interpreter.runCommand(command);
+ List facts = interpreter.getKnowledgeBase().getFacts();
+ List rules = interpreter.getKnowledgeBase().getRules();
+ List dataSourceDeclarations = interpreter.getKnowledgeBase().getDataSourceDeclarations();
+
+ assertEquals("assert", command.getName());
+ assertEquals(2, command.getArguments().size());
+ assertTrue(command.getArguments().get(0).fromPositiveLiteral().isPresent());
+ assertTrue(command.getArguments().get(1).fromRule().isPresent());
+
+ Literal literal = command.getArguments().get(0).fromPositiveLiteral().get();
+ Rule rule = command.getArguments().get(1).fromRule().get();
+
+ assertEquals(Arrays.asList(literal), facts);
+ assertEquals(Arrays.asList(rule), rules);
+ assertTrue(dataSourceDeclarations.isEmpty());
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentTerm_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@assert \"string\" .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentNonFact_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@assert p(?X) .");
+ interpreter.runCommand(command);
+ }
+
+ @Test
+ public void help_succeeds() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ CommandInterpreter commandInterpreter = new AssertCommandInterpreter();
+ InterpreterTest.checkHelpFormat(commandInterpreter, interpreter, writer);
+ }
+
+ @Test
+ public void synopsis_succeeds() throws ParsingException, CommandExecutionException {
+ CommandInterpreter commandInterpreter = new AssertCommandInterpreter();
+ InterpreterTest.checkSynopsisFormat(commandInterpreter);
+ }
+
+}
diff --git a/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/ClearCommandInterpreterTest.java b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/ClearCommandInterpreterTest.java
new file mode 100644
index 000000000..207cc68e1
--- /dev/null
+++ b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/ClearCommandInterpreterTest.java
@@ -0,0 +1,244 @@
+package org.semanticweb.rulewerk.commands;
+
+/*-
+ * #%L
+ * Rulewerk command execution support
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import static org.junit.Assert.*;
+
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.stream.Collectors;
+import java.util.stream.StreamSupport;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.semanticweb.rulewerk.core.exceptions.PrefixDeclarationException;
+import org.semanticweb.rulewerk.core.model.api.Command;
+import org.semanticweb.rulewerk.core.model.api.DataSource;
+import org.semanticweb.rulewerk.core.model.api.DataSourceDeclaration;
+import org.semanticweb.rulewerk.core.model.api.Fact;
+import org.semanticweb.rulewerk.core.model.api.PositiveLiteral;
+import org.semanticweb.rulewerk.core.model.api.Predicate;
+import org.semanticweb.rulewerk.core.model.api.PrefixDeclarationRegistry;
+import org.semanticweb.rulewerk.core.model.api.Rule;
+import org.semanticweb.rulewerk.core.model.api.Term;
+import org.semanticweb.rulewerk.core.model.implementation.DataSourceDeclarationImpl;
+import org.semanticweb.rulewerk.core.model.implementation.Expressions;
+import org.semanticweb.rulewerk.core.reasoner.KnowledgeBase;
+import org.semanticweb.rulewerk.core.reasoner.Reasoner;
+import org.semanticweb.rulewerk.parser.DefaultParserConfiguration;
+import org.semanticweb.rulewerk.parser.ParserConfiguration;
+import org.semanticweb.rulewerk.parser.ParsingException;
+
+public class ClearCommandInterpreterTest {
+
+ static Term a = Expressions.makeAbstractConstant("a");
+ static Term x = Expressions.makeUniversalVariable("X");
+ static Predicate p = Expressions.makePredicate("p", 1);
+ static Predicate q = Expressions.makePredicate("q", 1);
+ static Predicate r = Expressions.makePredicate("r", 1);
+ static Fact fact = Expressions.makeFact(p, a);
+ static PositiveLiteral headLiteral = Expressions.makePositiveLiteral(q, x);
+ static PositiveLiteral bodyLiteral = Expressions.makePositiveLiteral(r, x);
+ static Rule rule = Expressions.makeRule(headLiteral, bodyLiteral);
+ static Map standardPrefixes = new HashMap<>();
+ static {
+ standardPrefixes.put("eg:", "http://example.org/");
+ }
+ static DataSourceDeclaration dataSourceDeclaration = new DataSourceDeclarationImpl(p,
+ Mockito.mock(DataSource.class));
+
+ private void prepareKnowledgeBase(KnowledgeBase knowledgeBase) throws PrefixDeclarationException {
+ knowledgeBase.addStatement(fact);
+ knowledgeBase.addStatement(rule);
+ knowledgeBase.addStatement(dataSourceDeclaration);
+ knowledgeBase.getPrefixDeclarationRegistry().setPrefixIri("eg:", "http://example.org/");
+ }
+
+ private void assertPrefixesEqual(Map expectedPrefixes,
+ PrefixDeclarationRegistry prefixDeclarationRegistry) {
+ Set> prefixes = StreamSupport.stream(prefixDeclarationRegistry.spliterator(), false)
+ .collect(Collectors.toSet());
+ assertEquals(expectedPrefixes.entrySet(), prefixes);
+ }
+
+ @Test
+ public void correctUseAll_succeeds()
+ throws ParsingException, CommandExecutionException, PrefixDeclarationException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = Mockito.spy(InterpreterTest.getMockInterpreter(writer));
+ prepareKnowledgeBase(interpreter.getKnowledgeBase());
+
+ assertEquals(1, interpreter.getKnowledgeBase().getFacts().size());
+
+ Command command = interpreter.parseCommand("@clear ALL .");
+ interpreter.runCommand(command);
+
+ assertTrue(interpreter.getKnowledgeBase().getFacts().isEmpty());
+ assertTrue(interpreter.getKnowledgeBase().getRules().isEmpty());
+ assertTrue(interpreter.getKnowledgeBase().getDataSourceDeclarations().isEmpty());
+ assertPrefixesEqual(Collections.emptyMap(), interpreter.getKnowledgeBase().getPrefixDeclarationRegistry());
+ Mockito.verify(interpreter).clearReasonerAndKnowledgeBase();
+ }
+
+ @Test
+ public void correctUseInf_succeeds()
+ throws ParsingException, CommandExecutionException, PrefixDeclarationException {
+ StringWriter writer = new StringWriter();
+ SimpleStyledPrinter printer = new SimpleStyledPrinter(writer);
+ ParserConfiguration parserConfiguration = new DefaultParserConfiguration();
+ final KnowledgeBase knowledgeBase = new KnowledgeBase();
+ final Reasoner reasoner = Mockito.spy(Reasoner.class);
+ Mockito.when(reasoner.getKnowledgeBase()).thenReturn(knowledgeBase);
+ try (Interpreter interpreter = new Interpreter(() -> knowledgeBase, (kb) -> reasoner, printer,
+ parserConfiguration)) {
+ prepareKnowledgeBase(interpreter.getKnowledgeBase());
+
+ Command command = interpreter.parseCommand("@clear INF .");
+ interpreter.runCommand(command);
+
+ assertEquals(Arrays.asList(fact), interpreter.getKnowledgeBase().getFacts());
+ assertEquals(Arrays.asList(rule), interpreter.getKnowledgeBase().getRules());
+ assertEquals(Arrays.asList(dataSourceDeclaration),
+ interpreter.getKnowledgeBase().getDataSourceDeclarations());
+ assertPrefixesEqual(standardPrefixes, interpreter.getKnowledgeBase().getPrefixDeclarationRegistry());
+ Mockito.verify(reasoner).resetReasoner();
+ }
+ }
+
+ @Test
+ public void correctUseFacts_succeeds()
+ throws ParsingException, CommandExecutionException, PrefixDeclarationException {
+ StringWriter writer = new StringWriter();
+ try (Interpreter interpreter = InterpreterTest.getMockInterpreter(writer)) {
+ prepareKnowledgeBase(interpreter.getKnowledgeBase());
+
+ Command command = interpreter.parseCommand("@clear FACTS .");
+ interpreter.runCommand(command);
+
+ assertTrue(interpreter.getKnowledgeBase().getFacts().isEmpty());
+ assertEquals(Arrays.asList(rule), interpreter.getKnowledgeBase().getRules());
+ assertEquals(Arrays.asList(dataSourceDeclaration),
+ interpreter.getKnowledgeBase().getDataSourceDeclarations());
+ assertPrefixesEqual(standardPrefixes, interpreter.getKnowledgeBase().getPrefixDeclarationRegistry());
+ }
+ }
+
+ @Test
+ public void correctUseRules_succeeds()
+ throws ParsingException, CommandExecutionException, PrefixDeclarationException {
+ StringWriter writer = new StringWriter();
+ try (Interpreter interpreter = InterpreterTest.getMockInterpreter(writer)) {
+ prepareKnowledgeBase(interpreter.getKnowledgeBase());
+
+ Command command = interpreter.parseCommand("@clear RULES .");
+ interpreter.runCommand(command);
+
+ assertEquals(Arrays.asList(fact), interpreter.getKnowledgeBase().getFacts());
+ assertTrue(interpreter.getKnowledgeBase().getRules().isEmpty());
+ assertEquals(Arrays.asList(dataSourceDeclaration),
+ interpreter.getKnowledgeBase().getDataSourceDeclarations());
+ assertPrefixesEqual(standardPrefixes, interpreter.getKnowledgeBase().getPrefixDeclarationRegistry());
+ }
+ }
+
+ @Test
+ public void correctUseSources_succeeds()
+ throws ParsingException, CommandExecutionException, PrefixDeclarationException {
+ StringWriter writer = new StringWriter();
+ try (Interpreter interpreter = InterpreterTest.getMockInterpreter(writer)) {
+ prepareKnowledgeBase(interpreter.getKnowledgeBase());
+
+ Command command = interpreter.parseCommand("@clear DATASOURCES .");
+ interpreter.runCommand(command);
+
+ assertEquals(Arrays.asList(fact), interpreter.getKnowledgeBase().getFacts());
+ assertEquals(Arrays.asList(rule), interpreter.getKnowledgeBase().getRules());
+ assertTrue(interpreter.getKnowledgeBase().getDataSourceDeclarations().isEmpty());
+ assertPrefixesEqual(standardPrefixes, interpreter.getKnowledgeBase().getPrefixDeclarationRegistry());
+ }
+ }
+
+ @Test
+ public void correctUsePrefixes_succeeds()
+ throws ParsingException, CommandExecutionException, PrefixDeclarationException {
+ StringWriter writer = new StringWriter();
+ try (Interpreter interpreter = InterpreterTest.getMockInterpreter(writer)) {
+
+ prepareKnowledgeBase(interpreter.getKnowledgeBase());
+
+ Command command = interpreter.parseCommand("@clear PREFIXES .");
+ interpreter.runCommand(command);
+
+ assertEquals(Arrays.asList(fact), interpreter.getKnowledgeBase().getFacts());
+ assertEquals(Arrays.asList(rule), interpreter.getKnowledgeBase().getRules());
+ assertEquals(Arrays.asList(dataSourceDeclaration),
+ interpreter.getKnowledgeBase().getDataSourceDeclarations());
+ assertPrefixesEqual(Collections.emptyMap(), interpreter.getKnowledgeBase().getPrefixDeclarationRegistry());
+ }
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentCount_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@clear .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentType_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@clear \"string\" .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void unkonwnTask_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@clear UNKNOWNTASK .");
+ interpreter.runCommand(command);
+ }
+
+ @Test
+ public void help_succeeds() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ CommandInterpreter commandInterpreter = new ClearCommandInterpreter();
+ InterpreterTest.checkHelpFormat(commandInterpreter, interpreter, writer);
+ }
+
+ @Test
+ public void synopsis_succeeds() throws ParsingException, CommandExecutionException {
+ CommandInterpreter commandInterpreter = new ClearCommandInterpreter();
+ InterpreterTest.checkSynopsisFormat(commandInterpreter);
+ }
+
+}
diff --git a/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/ExportCommandInterpreterTest.java b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/ExportCommandInterpreterTest.java
new file mode 100644
index 000000000..52207d1bf
--- /dev/null
+++ b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/ExportCommandInterpreterTest.java
@@ -0,0 +1,156 @@
+package org.semanticweb.rulewerk.commands;
+
+/*-
+ * #%L
+ * Rulewerk command execution support
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import static org.junit.Assert.*;
+
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.semanticweb.rulewerk.core.model.api.Command;
+import org.semanticweb.rulewerk.core.model.api.Fact;
+import org.semanticweb.rulewerk.core.model.api.Predicate;
+import org.semanticweb.rulewerk.core.model.api.Term;
+import org.semanticweb.rulewerk.core.model.implementation.Expressions;
+import org.semanticweb.rulewerk.core.reasoner.Correctness;
+import org.semanticweb.rulewerk.parser.ParsingException;
+
+public class ExportCommandInterpreterTest {
+
+ @Test
+ public void correctUseKb_succeeds() throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ StringWriter fileWriter = new StringWriter();
+ Interpreter origInterpreter = InterpreterTest.getMockInterpreter(writer);
+ Interpreter interpreter = Mockito.spy(origInterpreter);
+ Mockito.doReturn(fileWriter).when(interpreter).getFileWriter(Mockito.eq("test.rls"));
+ Predicate predicate = Expressions.makePredicate("p", 1);
+ Term term = Expressions.makeAbstractConstant("a");
+ Fact fact = Expressions.makeFact(predicate, term);
+ interpreter.getKnowledgeBase().addStatement(fact);
+
+ Command command = interpreter.parseCommand("@export KB \"test.rls\" .");
+ interpreter.runCommand(command);
+
+ StringWriter anotherWriter = new StringWriter();
+ interpreter.getKnowledgeBase().writeKnowledgeBase(anotherWriter);
+
+ assertEquals("export", command.getName());
+ assertEquals(2, command.getArguments().size());
+ assertEquals(anotherWriter.toString(), fileWriter.toString());
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void correctUseKbIoException_failse() throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter origInterpreter = InterpreterTest.getMockInterpreter(writer);
+ Interpreter interpreter = Mockito.spy(origInterpreter);
+ Mockito.doThrow(FileNotFoundException.class).when(interpreter).getFileWriter(Mockito.eq("test.rls"));
+
+ Command command = interpreter.parseCommand("@export KB \"test.rls\" .");
+ interpreter.runCommand(command);
+ }
+
+ @Test
+ public void correctUseInferences_succeeds() throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ StringWriter fileWriter = new StringWriter();
+ Interpreter origInterpreter = InterpreterTest.getMockInterpreter(writer);
+ Interpreter interpreter = Mockito.spy(origInterpreter);
+ Mockito.doReturn(fileWriter).when(interpreter).getFileWriter(Mockito.eq("test.rls"));
+ Mockito.when(interpreter.getReasoner().writeInferences(Mockito.any(Writer.class)))
+ .thenReturn(Correctness.SOUND_BUT_INCOMPLETE);
+
+ Command command = interpreter.parseCommand("@export INFERENCES \"test.rls\" .");
+ interpreter.runCommand(command);
+
+ assertEquals("export", command.getName());
+ assertEquals(2, command.getArguments().size());
+ assertTrue(writer.toString().contains(Correctness.SOUND_BUT_INCOMPLETE.toString()));
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void correctUseInferencesIoException_fails()
+ throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter origInterpreter = InterpreterTest.getMockInterpreter(writer);
+ Interpreter interpreter = Mockito.spy(origInterpreter);
+ Mockito.doThrow(FileNotFoundException.class).when(interpreter).getFileWriter(Mockito.eq("test.rls"));
+
+ Command command = interpreter.parseCommand("@export INFERENCES \"test.rls\" .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void unknonwTask_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@export UNKNOWN \"file.csv\" .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongFirstArgumentType_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@export \"string\" \"file.rls\".");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongSecondArgumentType_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@export KB 123 .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentCount_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@export KB \"file.rls\" more .");
+ interpreter.runCommand(command);
+ }
+
+ @Test
+ public void help_succeeds() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ CommandInterpreter commandInterpreter = new ExportCommandInterpreter();
+ InterpreterTest.checkHelpFormat(commandInterpreter, interpreter, writer);
+ }
+
+ @Test
+ public void synopsis_succeeds() throws ParsingException, CommandExecutionException {
+ CommandInterpreter commandInterpreter = new ExportCommandInterpreter();
+ InterpreterTest.checkSynopsisFormat(commandInterpreter);
+ }
+
+}
diff --git a/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/HelpCommandInterpreterTest.java b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/HelpCommandInterpreterTest.java
new file mode 100644
index 000000000..8a89c1cea
--- /dev/null
+++ b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/HelpCommandInterpreterTest.java
@@ -0,0 +1,117 @@
+package org.semanticweb.rulewerk.commands;
+
+/*-
+ * #%L
+ * Rulewerk command execution support
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import org.junit.Test;
+import org.semanticweb.rulewerk.core.model.api.Command;
+import org.semanticweb.rulewerk.parser.ParsingException;
+
+public class HelpCommandInterpreterTest {
+
+ @Test
+ public void correctUse_succeeds() throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@help .");
+ interpreter.runCommand(command);
+
+ String output = writer.toString();
+ for (String commandName : interpreter.getRegisteredCommands()) {
+ assertTrue(output.contains("@" + commandName));
+ }
+ }
+
+ @Test
+ public void correctUseWithCommand_succeeds() throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@help query.");
+ interpreter.runCommand(command);
+ // Nothing much to test here.
+ assertTrue(writer.toString().length() > 0);
+ }
+
+ @Test
+ public void wrongArgumentCount_succeeds() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@help query showkb .");
+ interpreter.runCommand(command);
+ // Nothing much to test here.
+ assertTrue(writer.toString().length() > 0);
+ }
+
+ @Test
+ public void unknownCommandHelp_succeeds() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@help unknowncommand .");
+ interpreter.runCommand(command);
+ // Nothing much to test here.
+ assertTrue(writer.toString().length() > 0);
+ }
+
+ @Test
+ public void wrongArgumentTypeTerm_succeeds() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@help 123 .");
+ interpreter.runCommand(command);
+ // Nothing much to test here.
+ assertTrue(writer.toString().length() > 0);
+ }
+
+ @Test
+ public void wrongArgumentTypeFact_succeeds() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@help p(a) .");
+ interpreter.runCommand(command);
+ // Nothing much to test here.
+ assertTrue(writer.toString().length() > 0);
+ }
+
+ @Test
+ public void help_succeeds() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ CommandInterpreter commandInterpreter = new HelpCommandInterpreter();
+ InterpreterTest.checkHelpFormat(commandInterpreter, interpreter, writer);
+ }
+
+ @Test
+ public void synopsis_succeeds() throws ParsingException, CommandExecutionException {
+ CommandInterpreter commandInterpreter = new HelpCommandInterpreter();
+ InterpreterTest.checkSynopsisFormat(commandInterpreter);
+ }
+
+}
diff --git a/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/InterpreterTest.java b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/InterpreterTest.java
new file mode 100644
index 000000000..443ed8baa
--- /dev/null
+++ b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/InterpreterTest.java
@@ -0,0 +1,141 @@
+package org.semanticweb.rulewerk.commands;
+
+/*-
+ * #%L
+ * Rulewerk command execution support
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import static org.junit.Assert.*;
+
+import java.io.StringWriter;
+import java.io.Writer;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.semanticweb.rulewerk.core.exceptions.PrefixDeclarationException;
+import org.semanticweb.rulewerk.core.model.api.Command;
+import org.semanticweb.rulewerk.core.reasoner.KnowledgeBase;
+import org.semanticweb.rulewerk.core.reasoner.Reasoner;
+import org.semanticweb.rulewerk.parser.DefaultParserConfiguration;
+import org.semanticweb.rulewerk.parser.ParserConfiguration;
+import org.semanticweb.rulewerk.parser.ParsingException;
+
+public class InterpreterTest {
+
+ static public Interpreter getMockInterpreter(Writer writer) {
+ SimpleStyledPrinter printer = new SimpleStyledPrinter(writer);
+ ParserConfiguration parserConfiguration = new DefaultParserConfiguration();
+ return new Interpreter(Interpreter.EMPTY_KNOWLEDGE_BASE_PROVIDER, (knowledgeBase) -> {
+ Reasoner reasoner = Mockito.mock(Reasoner.class);
+ Mockito.when(reasoner.getKnowledgeBase()).thenReturn(knowledgeBase);
+ return reasoner;
+ }, printer, parserConfiguration);
+ }
+
+ /**
+ * Checks the basic format of command usage instructions and verifies that the
+ * given command name is used (not a fixed one).
+ *
+ * @param commandInterpreter
+ * @param interpreter
+ * @param writer
+ */
+ static public void checkHelpFormat(CommandInterpreter commandInterpreter, Interpreter interpreter,
+ StringWriter writer) {
+ commandInterpreter.printHelp("commandname", interpreter);
+ String result = writer.toString();
+
+ assertTrue(result.startsWith("Usage: @commandname "));
+ assertTrue(result.endsWith("\n"));
+ }
+
+ static public void checkSynopsisFormat(CommandInterpreter commandInterpreter) {
+ String synopsis = commandInterpreter.getSynopsis();
+ assertTrue(synopsis.length() < 70);
+ }
+
+ @Test
+ public void getters_succeed() {
+ StringWriter writer = new StringWriter();
+ SimpleStyledPrinter printer = new SimpleStyledPrinter(writer);
+ ParserConfiguration parserConfiguration = new DefaultParserConfiguration();
+ final KnowledgeBase knowledgeBase = new KnowledgeBase();
+ final Reasoner reasoner = Mockito.mock(Reasoner.class);
+ Mockito.when(reasoner.getKnowledgeBase()).thenReturn(knowledgeBase);
+ try (Interpreter interpreter = new Interpreter(() -> knowledgeBase, (kb) -> reasoner, printer,
+ parserConfiguration)) {
+ assertEquals(knowledgeBase, interpreter.getKnowledgeBase());
+ assertEquals(reasoner, interpreter.getReasoner());
+ assertEquals(writer, interpreter.getWriter());
+ assertEquals(parserConfiguration, interpreter.getParserConfiguration());
+ }
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void unknownCommand_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ try (Interpreter interpreter = getMockInterpreter(writer)) {
+ Command command = interpreter.parseCommand("@unknown .");
+ interpreter.runCommand(command);
+ }
+ }
+
+ @Test(expected = ParsingException.class)
+ public void malformedCommand_fails() throws ParsingException {
+ StringWriter writer = new StringWriter();
+ try (Interpreter interpreter = getMockInterpreter(writer)) {
+ interpreter.parseCommand("malformed .");
+ }
+ }
+
+ @Test
+ public void prefixesAreUsed_succeeds() throws ParsingException, PrefixDeclarationException {
+ StringWriter writer = new StringWriter();
+ try (Interpreter interpreter = InterpreterTest.getMockInterpreter(writer)) {
+ interpreter.getKnowledgeBase().getPrefixDeclarationRegistry().setPrefixIri("eg:", "http://example.org/");
+
+ Command command = interpreter.parseCommand("@somecommand eg:test .");
+
+ assertEquals(1, command.getArguments().size());
+ assertTrue(command.getArguments().get(0).fromTerm().isPresent());
+ assertEquals("http://example.org/test", command.getArguments().get(0).fromTerm().get().getName());
+ }
+ }
+
+ @Test
+ public void print_succeeds() {
+ StringWriter writer = new StringWriter();
+ SimpleStyledPrinter printer = Mockito.spy(new SimpleStyledPrinter(writer));
+ ParserConfiguration parserConfiguration = new DefaultParserConfiguration();
+ try (Interpreter interpreter = new Interpreter(Interpreter.EMPTY_KNOWLEDGE_BASE_PROVIDER,
+ (kb) -> Mockito.mock(Reasoner.class), printer, parserConfiguration)) {
+ interpreter.printCode("Code");
+ interpreter.printNormal("Normal");
+ interpreter.printEmph("Emph");
+ interpreter.printSection("Section");
+ interpreter.printImportant("Important");
+
+ Mockito.verify(printer).printCode("Code");
+ Mockito.verify(printer).printNormal("Normal");
+ Mockito.verify(printer).printEmph("Emph");
+ Mockito.verify(printer).printSection("Section");
+ Mockito.verify(printer).printImportant("Important");
+ }
+ }
+
+}
diff --git a/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/LoadCommandInterpreterTest.java b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/LoadCommandInterpreterTest.java
new file mode 100644
index 000000000..ee3d1ac42
--- /dev/null
+++ b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/LoadCommandInterpreterTest.java
@@ -0,0 +1,359 @@
+package org.semanticweb.rulewerk.commands;
+
+/*-
+ * #%L
+ * Rulewerk command execution support
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import static org.junit.Assert.*;
+
+import java.io.ByteArrayInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+import java.util.Arrays;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.semanticweb.rulewerk.core.exceptions.PrefixDeclarationException;
+import org.semanticweb.rulewerk.core.model.api.Command;
+import org.semanticweb.rulewerk.core.model.api.Fact;
+import org.semanticweb.rulewerk.core.model.api.Predicate;
+import org.semanticweb.rulewerk.core.model.api.Term;
+import org.semanticweb.rulewerk.core.model.implementation.Expressions;
+import org.semanticweb.rulewerk.parser.ParsingException;
+
+public class LoadCommandInterpreterTest {
+
+ @Test
+ public void correctUse_succeeds() throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ InputStream inputStream = new ByteArrayInputStream("p(a) .".getBytes(StandardCharsets.UTF_8));
+ Interpreter origInterpreter = InterpreterTest.getMockInterpreter(writer);
+ Interpreter interpreter = Mockito.spy(origInterpreter);
+ Mockito.doReturn(inputStream).when(interpreter).getFileInputStream(Mockito.eq("loadtest.rls"));
+
+ Predicate predicate = Expressions.makePredicate("p", 1);
+ Term term = Expressions.makeAbstractConstant("a");
+ Fact fact = Expressions.makeFact(predicate, term);
+
+ Command command = interpreter.parseCommand("@load 'loadtest.rls' .");
+ interpreter.runCommand(command);
+
+ assertEquals("load", command.getName());
+ assertEquals(1, command.getArguments().size());
+ assertTrue(command.getArguments().get(0).fromTerm().isPresent());
+
+ assertEquals(Arrays.asList(fact), interpreter.getKnowledgeBase().getFacts());
+ assertTrue(interpreter.getKnowledgeBase().getRules().isEmpty());
+ assertTrue(interpreter.getKnowledgeBase().getDataSourceDeclarations().isEmpty());
+ }
+
+ @Test
+ public void correctUseWithRulesTask_succeeds() throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ InputStream inputStream = new ByteArrayInputStream("p(a) .".getBytes(StandardCharsets.UTF_8));
+ Interpreter origInterpreter = InterpreterTest.getMockInterpreter(writer);
+ Interpreter interpreter = Mockito.spy(origInterpreter);
+ Mockito.doReturn(inputStream).when(interpreter).getFileInputStream(Mockito.eq("loadtest.rls"));
+
+ Predicate predicate = Expressions.makePredicate("p", 1);
+ Term term = Expressions.makeAbstractConstant("a");
+ Fact fact = Expressions.makeFact(predicate, term);
+
+ Command command = interpreter.parseCommand("@load RULES 'loadtest.rls' .");
+ interpreter.runCommand(command);
+
+ assertEquals(Arrays.asList(fact), interpreter.getKnowledgeBase().getFacts());
+ assertTrue(interpreter.getKnowledgeBase().getRules().isEmpty());
+ assertTrue(interpreter.getKnowledgeBase().getDataSourceDeclarations().isEmpty());
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void correctUseParseError_fails() throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ InputStream inputStream = new ByteArrayInputStream("not parsable".getBytes(StandardCharsets.UTF_8));
+ Interpreter origInterpreter = InterpreterTest.getMockInterpreter(writer);
+ Interpreter interpreter = Mockito.spy(origInterpreter);
+ Mockito.doReturn(inputStream).when(interpreter).getFileInputStream(Mockito.eq("loadtest.rls"));
+
+ Command command = interpreter.parseCommand("@load 'loadtest.rls' .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void correctUseFileNotFoundError_fails() throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter origInterpreter = InterpreterTest.getMockInterpreter(writer);
+ Interpreter interpreter = Mockito.spy(origInterpreter);
+ Mockito.doThrow(FileNotFoundException.class).when(interpreter).getFileInputStream(Mockito.eq("loadtest.rls"));
+
+ Command command = interpreter.parseCommand("@load 'loadtest.rls' .");
+ interpreter.runCommand(command);
+ }
+
+ @Test
+ public void correctUseWithOwlTask_succeeds() throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Predicate predicate = Expressions.makePredicate("http://example.org/C", 1);
+ Term term = Expressions.makeAbstractConstant("http://example.org/a");
+ Fact fact = Expressions.makeFact(predicate, term);
+
+ Command command = interpreter.parseCommand("@load OWL 'src/test/data/loadtest.owl' .");
+ interpreter.runCommand(command);
+
+ assertEquals(Arrays.asList(fact), interpreter.getKnowledgeBase().getFacts());
+ assertTrue(interpreter.getKnowledgeBase().getRules().isEmpty());
+ assertTrue(interpreter.getKnowledgeBase().getDataSourceDeclarations().isEmpty());
+ }
+
+ @Test
+ public void correctUseWithOwlTask_UnsupportedAxioms_succeeds()
+ throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Predicate predicate = Expressions.makePredicate("http://example.org/C", 1);
+ Term term = Expressions.makeAbstractConstant("http://example.org/a");
+ Fact fact = Expressions.makeFact(predicate, term);
+
+ Command command = interpreter.parseCommand("@load OWL 'src/test/data/loadtest-unsupported.owl' .");
+ interpreter.runCommand(command);
+
+ assertEquals(Arrays.asList(fact), interpreter.getKnowledgeBase().getFacts());
+ assertTrue(interpreter.getKnowledgeBase().getRules().isEmpty());
+ assertTrue(interpreter.getKnowledgeBase().getDataSourceDeclarations().isEmpty());
+ // OUtput mentions the offending axiom in Functional-Style Syntax:
+ assertTrue(writer.toString().contains("InverseFunctionalObjectProperty()"));
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void correctUseWithOwlTask_malformedOwl_fails()
+ throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@load OWL 'src/test/data/loadtest-fails.owl' .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void correctUseWithOwlTask_missingFile_fails()
+ throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@load OWL 'src/test/data/file-does-not-exist.owl' .");
+ interpreter.runCommand(command);
+ }
+
+ @Test
+ public void correctUseWithRdfTask_Nt_succeeds()
+ throws ParsingException, CommandExecutionException, IOException, PrefixDeclarationException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Predicate predicate = Expressions.makePredicate("TRIPLE", 3);
+ Term terma = Expressions.makeAbstractConstant("http://example.org/a");
+ Term termb = Expressions.makeAbstractConstant("http://example.org/b");
+ Term termc = Expressions.makeAbstractConstant("http://example.org/c");
+ Fact fact = Expressions.makeFact(predicate, terma, termb, termc);
+
+ Command command = interpreter.parseCommand("@load RDF 'src/test/data/loadtest.nt' .");
+ interpreter.runCommand(command);
+
+ assertEquals(Arrays.asList(fact), interpreter.getKnowledgeBase().getFacts());
+ assertTrue(interpreter.getKnowledgeBase().getRules().isEmpty());
+ assertTrue(interpreter.getKnowledgeBase().getDataSourceDeclarations().isEmpty());
+ }
+
+ @Test
+ public void correctUseWithRdfTask_NtCustomPredicate_succeeds()
+ throws ParsingException, CommandExecutionException, IOException, PrefixDeclarationException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Predicate predicate = Expressions.makePredicate("http://example.org/mytriple", 3);
+ Term terma = Expressions.makeAbstractConstant("http://example.org/a");
+ Term termb = Expressions.makeAbstractConstant("http://example.org/b");
+ Term termc = Expressions.makeAbstractConstant("http://example.org/c");
+ Fact fact = Expressions.makeFact(predicate, terma, termb, termc);
+
+ Command command = interpreter
+ .parseCommand("@load RDF 'src/test/data/loadtest.nt' .");
+ interpreter.runCommand(command);
+
+ assertEquals(Arrays.asList(fact), interpreter.getKnowledgeBase().getFacts());
+ assertTrue(interpreter.getKnowledgeBase().getRules().isEmpty());
+ assertTrue(interpreter.getKnowledgeBase().getDataSourceDeclarations().isEmpty());
+ }
+
+ @Test
+ public void correctUseWithRdfTask_NtABoxLoading_succeeds()
+ throws ParsingException, CommandExecutionException, IOException, PrefixDeclarationException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Predicate predicate = Expressions.makePredicate("http://example.org/b", 2);
+ Term terma = Expressions.makeAbstractConstant("http://example.org/a");
+ Term termc = Expressions.makeAbstractConstant("http://example.org/c");
+ Fact fact = Expressions.makeFact(predicate, terma, termc);
+
+ Command command = interpreter.parseCommand("@load RDF 'src/test/data/loadtest.nt' ABOX.");
+ interpreter.runCommand(command);
+
+ assertEquals(Arrays.asList(fact), interpreter.getKnowledgeBase().getFacts());
+ assertTrue(interpreter.getKnowledgeBase().getRules().isEmpty());
+ assertTrue(interpreter.getKnowledgeBase().getDataSourceDeclarations().isEmpty());
+ }
+
+ @Test
+ public void correctUseWithRdfTask_Turtle_succeeds()
+ throws ParsingException, CommandExecutionException, IOException, PrefixDeclarationException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Predicate predicate = Expressions.makePredicate("TRIPLE", 3);
+ Term terma = Expressions.makeAbstractConstant("http://example.org/a");
+ Term termb = Expressions.makeAbstractConstant("http://example.org/b");
+ Term termc = Expressions.makeAbstractConstant("http://example.org/c");
+ Fact fact = Expressions.makeFact(predicate, terma, termb, termc);
+
+ Command command = interpreter.parseCommand("@load RDF 'src/test/data/loadtest.ttl' .");
+ interpreter.runCommand(command);
+
+ assertEquals(Arrays.asList(fact), interpreter.getKnowledgeBase().getFacts());
+ assertEquals("http://example.org/", interpreter.getKnowledgeBase().getPrefixIri(":"));
+ assertTrue(interpreter.getKnowledgeBase().getRules().isEmpty());
+ assertTrue(interpreter.getKnowledgeBase().getDataSourceDeclarations().isEmpty());
+ }
+
+ @Test
+ public void correctUseWithRdfTask_RdfXml_succeeds()
+ throws ParsingException, CommandExecutionException, IOException, PrefixDeclarationException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Predicate predicate = Expressions.makePredicate("TRIPLE", 3);
+ Term terma = Expressions.makeAbstractConstant("http://example.org/a");
+ Term termb = Expressions.makeAbstractConstant("http://example.org/b");
+ Term termc = Expressions.makeAbstractConstant("http://example.org/c");
+ Fact fact = Expressions.makeFact(predicate, terma, termb, termc);
+
+ Command command = interpreter.parseCommand("@load RDF 'src/test/data/loadtest.rdf' .");
+ interpreter.runCommand(command);
+
+ assertEquals(Arrays.asList(fact), interpreter.getKnowledgeBase().getFacts());
+ assertEquals("http://example.org/", interpreter.getKnowledgeBase().getPrefixIri("eg:"));
+ assertTrue(interpreter.getKnowledgeBase().getRules().isEmpty());
+ assertTrue(interpreter.getKnowledgeBase().getDataSourceDeclarations().isEmpty());
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void correctUseWithRdfTask_malformedRdf_fails()
+ throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@load RDF 'src/test/data/loadtest-fails.owl' .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void correctUseWithRdfTask_missingFile_fails()
+ throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@load RDF 'src/test/data/file-does-not-exist.rdf' .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentCount_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@load .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentCountWithOptional_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@load OWL .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongRdfPredicateTermType_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@load RDF \"file.nt\" \"string\" .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongRdfPredicateArgumentType_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@load RDF \"file.nt\" p(a) .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentType_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@load p(a) .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongTask_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@load UNKOWNTASK 'loadtest.rls' .");
+ interpreter.runCommand(command);
+ }
+
+ @Test
+ public void help_succeeds() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ CommandInterpreter commandInterpreter = new LoadCommandInterpreter();
+ InterpreterTest.checkHelpFormat(commandInterpreter, interpreter, writer);
+ }
+
+ @Test
+ public void synopsis_succeeds() throws ParsingException, CommandExecutionException {
+ CommandInterpreter commandInterpreter = new LoadCommandInterpreter();
+ InterpreterTest.checkSynopsisFormat(commandInterpreter);
+ }
+
+}
diff --git a/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/QueryCommandInterpreterTest.java b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/QueryCommandInterpreterTest.java
new file mode 100644
index 000000000..a23f72b13
--- /dev/null
+++ b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/QueryCommandInterpreterTest.java
@@ -0,0 +1,313 @@
+package org.semanticweb.rulewerk.commands;
+
+/*-
+ * #%L
+ * Rulewerk command execution support
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.semanticweb.rulewerk.core.model.api.Command;
+import org.semanticweb.rulewerk.core.model.api.QueryResult;
+import org.semanticweb.rulewerk.core.model.implementation.Expressions;
+import org.semanticweb.rulewerk.core.reasoner.Correctness;
+import org.semanticweb.rulewerk.core.reasoner.QueryAnswerCount;
+import org.semanticweb.rulewerk.core.reasoner.QueryResultIterator;
+import org.semanticweb.rulewerk.core.reasoner.implementation.QueryAnswerCountImpl;
+import org.semanticweb.rulewerk.core.reasoner.implementation.QueryResultImpl;
+import org.semanticweb.rulewerk.parser.ParsingException;
+
+public class QueryCommandInterpreterTest {
+
+ class TestQueryResultIterator implements QueryResultIterator {
+
+ final Iterator results;
+
+ public TestQueryResultIterator(List results) {
+ this.results = results.iterator();
+ }
+
+ @Override
+ public boolean hasNext() {
+ return results.hasNext();
+ }
+
+ @Override
+ public QueryResult next() {
+ return results.next();
+ }
+
+ @Override
+ public Correctness getCorrectness() {
+ return Correctness.SOUND_AND_COMPLETE;
+ }
+
+ @Override
+ public void close() {
+ }
+
+ }
+
+ @Test
+ public void correctUseQuery_succeeds() throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ QueryResult r1 = new QueryResultImpl(Arrays.asList(Expressions.makeAbstractConstant("#TEST-1#")));
+ QueryResult r2 = new QueryResultImpl(Arrays.asList(Expressions.makeAbstractConstant("#TEST-2#")));
+ QueryResult r3 = new QueryResultImpl(Arrays.asList(Expressions.makeAbstractConstant("#TEST-3#")));
+
+ QueryResultIterator results = new TestQueryResultIterator(Arrays.asList(r1, r2, r3));
+
+ Mockito.when(interpreter.getReasoner().answerQuery(Mockito.any(), Mockito.eq(true))).thenReturn(results);
+
+ Command command = interpreter.parseCommand("@query p(?X) LIMIT 2 .");
+ interpreter.runCommand(command);
+ // correct operation largely verified by not throwing an exception on the
+ // previous line, since only very few calls to the reasoner are not mocked
+ String output = writer.toString();
+
+ assertEquals("query", command.getName());
+ assertEquals(3, command.getArguments().size());
+ assertTrue(output.contains("#TEST-1#"));
+ assertTrue(output.contains("#TEST-2#"));
+ assertFalse(output.contains("#TEST-3#"));
+ assertTrue(output.contains(Correctness.SOUND_AND_COMPLETE.toString()));
+ }
+
+ @Test
+ public void correctUseBooleanQueryTrue_succeeds() throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ QueryResult r1 = new QueryResultImpl(Arrays.asList(Expressions.makeAbstractConstant("TEST-1")));
+ QueryResult r2 = new QueryResultImpl(Arrays.asList(Expressions.makeAbstractConstant("#TEST-2#")));
+ QueryResult r3 = new QueryResultImpl(Arrays.asList(Expressions.makeAbstractConstant("#TEST-3#")));
+
+ QueryResultIterator results = new TestQueryResultIterator(Arrays.asList(r1, r2, r3));
+
+ Mockito.when(interpreter.getReasoner().answerQuery(Mockito.any(), Mockito.eq(true))).thenReturn(results);
+
+ Command command = interpreter.parseCommand("@query p(TEST-1) LIMIT 2 .");
+ interpreter.runCommand(command);
+ // correct operation largely verified by not throwing an exception on the
+ // previous line, since only very few calls to the reasoner are not mocked
+ String output = writer.toString();
+
+ assertEquals("query", command.getName());
+ assertEquals(3, command.getArguments().size());
+ assertFalse(output.contains("TEST-1"));
+ assertFalse(output.contains("#TEST-2#"));
+ assertFalse(output.contains("#TEST-3#"));
+ assertTrue(output.startsWith("true"));
+ assertTrue(output.contains(Correctness.SOUND_AND_COMPLETE.toString()));
+ }
+
+ @Test
+ public void correctUseBooleanQueryFalse_succeeds() throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ QueryResultIterator results = new TestQueryResultIterator(Arrays.asList());
+
+ Mockito.when(interpreter.getReasoner().answerQuery(Mockito.any(), Mockito.eq(true))).thenReturn(results);
+
+ Command command = interpreter.parseCommand("@query p(TEST-1) LIMIT 2 .");
+ interpreter.runCommand(command);
+ // correct operation largely verified by not throwing an exception on the
+ // previous line, since only very few calls to the reasoner are not mocked
+ String output = writer.toString();
+
+ assertEquals("query", command.getName());
+ assertEquals(3, command.getArguments().size());
+ assertTrue(output.startsWith("false"));
+ assertTrue(output.contains(Correctness.SOUND_AND_COMPLETE.toString()));
+ }
+
+ @Test
+ public void correctUseCount_succeeds() throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ QueryAnswerCount queryAnswerCount = new QueryAnswerCountImpl(Correctness.SOUND_AND_COMPLETE, 42);
+ Mockito.when(interpreter.getReasoner().countQueryAnswers(Mockito.any(), Mockito.eq(true)))
+ .thenReturn(queryAnswerCount);
+ Mockito.when(interpreter.getReasoner().countQueryAnswers(Mockito.any())).thenReturn(queryAnswerCount);
+
+ Command command = interpreter.parseCommand("@query COUNT p(?X) .");
+ interpreter.runCommand(command);
+ // correct operation largely verified by not throwing an exception on the
+ // previous line, since only very few calls to the reasoner are not mocked
+
+ assertEquals("query", command.getName());
+ assertEquals(2, command.getArguments().size());
+ assertTrue(writer.toString().startsWith("42\n"));
+ assertTrue(writer.toString().contains(Correctness.SOUND_AND_COMPLETE.toString()));
+ }
+
+ @Test
+ public void correctUseExport_succeeds() throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Mockito.when(interpreter.getReasoner().exportQueryAnswersToCsv(Mockito.any(), Mockito.eq("file.csv"),
+ Mockito.anyBoolean())).thenReturn(Correctness.SOUND_BUT_INCOMPLETE);
+
+ Command command = interpreter.parseCommand("@query p(?X) EXPORTCSV \"file.csv\" .");
+ interpreter.runCommand(command);
+ // correct operation largely verified by not throwing an exception on the
+ // previous line, since only very few calls to the reasoner are not mocked
+
+ assertEquals("query", command.getName());
+ assertEquals(3, command.getArguments().size());
+ assertTrue(writer.toString().contains(Correctness.SOUND_BUT_INCOMPLETE.toString()));
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void exportIoError_fails() throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Mockito.when(interpreter.getReasoner().exportQueryAnswersToCsv(Mockito.any(), Mockito.eq("file.csv"),
+ Mockito.anyBoolean())).thenThrow(IOException.class);
+
+ Command command = interpreter.parseCommand("@query p(?X) EXPORTCSV \"file.csv\" .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentCountZero_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@query .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentNoLiteral_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@query COUNT LIMIT 10 .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentCountWithLimit_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@query COUNT p(?X) LIMIT 10 .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentCountWithExportFile_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@query COUNT p(?X) EXPORTCSV \"file.csv\" .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentWrongLimitTerm_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@query p(?X) LIMIT \"10\" .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentWrongLimitNoTerm_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@query p(?X) LIMIT p(a) .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentMissingLimit_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@query p(?X) LIMIT .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentWrongExportFileTerm_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@query p(?X) EXPORTCSV 123 .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentWrongExportFileNoTerm_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@query p(?X) EXPORTCSV p(a) .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentMissingExportFile_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@query p(?X) EXPORTCSV .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentExportWithLimit_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@query p(?X) LIMIT 10 EXPORTCSV \"test.csv\" .");
+ interpreter.runCommand(command);
+ }
+
+ @Test
+ public void help_succeeds() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ CommandInterpreter commandInterpreter = new QueryCommandInterpreter();
+ InterpreterTest.checkHelpFormat(commandInterpreter, interpreter, writer);
+ }
+
+ @Test
+ public void synopsis_succeeds() throws ParsingException, CommandExecutionException {
+ CommandInterpreter commandInterpreter = new QueryCommandInterpreter();
+ InterpreterTest.checkSynopsisFormat(commandInterpreter);
+ }
+
+}
diff --git a/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/ReasonCommandInterpreterTest.java b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/ReasonCommandInterpreterTest.java
new file mode 100644
index 000000000..025540d02
--- /dev/null
+++ b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/ReasonCommandInterpreterTest.java
@@ -0,0 +1,85 @@
+package org.semanticweb.rulewerk.commands;
+
+/*-
+ * #%L
+ * Rulewerk command execution support
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.semanticweb.rulewerk.core.model.api.Command;
+import org.semanticweb.rulewerk.core.reasoner.Correctness;
+import org.semanticweb.rulewerk.parser.ParsingException;
+
+public class ReasonCommandInterpreterTest {
+
+ @Test
+ public void correctUse_succeeds() throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ Mockito.when(interpreter.getReasoner().getCorrectness()).thenReturn(Correctness.SOUND_BUT_INCOMPLETE);
+ Mockito.when(interpreter.getReasoner().reason()).thenAnswer(I -> {
+ Mockito.when(interpreter.getReasoner().getCorrectness()).thenReturn(Correctness.SOUND_AND_COMPLETE);
+ return true;
+ });
+
+ Command command = interpreter.parseCommand("@reason .");
+ interpreter.runCommand(command);
+
+ assertEquals(Correctness.SOUND_AND_COMPLETE, interpreter.getReasoner().getCorrectness());
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void correctUseReasonerException_fails() throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ Mockito.when(interpreter.getReasoner().reason()).thenThrow(IOException.class);
+
+ Command command = interpreter.parseCommand("@reason .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentCount_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@reason p(?X) .");
+ interpreter.runCommand(command);
+ }
+
+ @Test
+ public void help_succeeds() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ CommandInterpreter commandInterpreter = new ReasonCommandInterpreter();
+ InterpreterTest.checkHelpFormat(commandInterpreter, interpreter, writer);
+ }
+
+ @Test
+ public void synopsis_succeeds() throws ParsingException, CommandExecutionException {
+ CommandInterpreter commandInterpreter = new ReasonCommandInterpreter();
+ InterpreterTest.checkSynopsisFormat(commandInterpreter);
+ }
+
+}
diff --git a/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/RemoveSourceCommandInterpreterTest.java b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/RemoveSourceCommandInterpreterTest.java
new file mode 100644
index 000000000..c5532acf9
--- /dev/null
+++ b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/RemoveSourceCommandInterpreterTest.java
@@ -0,0 +1,176 @@
+package org.semanticweb.rulewerk.commands;
+
+/*-
+ * #%L
+ * Rulewerk command execution support
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import static org.junit.Assert.*;
+
+import java.io.StringWriter;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+import org.semanticweb.rulewerk.core.model.api.Command;
+import org.semanticweb.rulewerk.core.model.api.DataSource;
+import org.semanticweb.rulewerk.core.model.api.DataSourceDeclaration;
+import org.semanticweb.rulewerk.core.model.api.Fact;
+import org.semanticweb.rulewerk.core.model.api.Predicate;
+import org.semanticweb.rulewerk.core.model.api.Rule;
+import org.semanticweb.rulewerk.core.model.implementation.DataSourceDeclarationImpl;
+import org.semanticweb.rulewerk.core.model.implementation.Expressions;
+import org.semanticweb.rulewerk.core.reasoner.implementation.SparqlQueryResultDataSource;
+import org.semanticweb.rulewerk.parser.ParsingException;
+
+public class RemoveSourceCommandInterpreterTest {
+
+ @Test
+ public void correctUse_succeeds() throws ParsingException, CommandExecutionException, MalformedURLException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ Predicate predicate = Expressions.makePredicate("p", 1);
+ DataSource dataSource = new SparqlQueryResultDataSource(new URL("http://example.org"), "?x", "?x ");
+ DataSourceDeclaration dataSourceDeclaration = new DataSourceDeclarationImpl(predicate, dataSource);
+ interpreter.getKnowledgeBase().addStatement(dataSourceDeclaration);
+
+ Command command = interpreter
+ .parseCommand("@delsource p[1] : sparql(, \"?x\", \"?x \") .");
+ interpreter.runCommand(command);
+ List facts = interpreter.getKnowledgeBase().getFacts();
+ List rules = interpreter.getKnowledgeBase().getRules();
+ List dataSourceDeclarations = interpreter.getKnowledgeBase().getDataSourceDeclarations();
+
+ assertEquals("delsource", command.getName());
+ assertEquals(2, command.getArguments().size());
+ assertTrue(command.getArguments().get(0).fromTerm().isPresent());
+ assertTrue(command.getArguments().get(1).fromPositiveLiteral().isPresent());
+
+ assertTrue(facts.isEmpty());
+ assertTrue(rules.isEmpty());
+ assertTrue(dataSourceDeclarations.isEmpty());
+ }
+
+ @Test
+ public void correctUseNothingRemoved_succeeds()
+ throws ParsingException, CommandExecutionException, MalformedURLException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ Predicate predicate = Expressions.makePredicate("p", 1);
+ DataSource dataSource = new SparqlQueryResultDataSource(new URL("http://example.org"), "?x", "?x ");
+ DataSourceDeclaration dataSourceDeclaration = new DataSourceDeclarationImpl(predicate, dataSource);
+ interpreter.getKnowledgeBase().addStatement(dataSourceDeclaration);
+
+ Command command = interpreter
+ .parseCommand("@delsource another[1] : sparql(, \"?x\", \"?x \") .");
+ interpreter.runCommand(command);
+ List facts = interpreter.getKnowledgeBase().getFacts();
+ List rules = interpreter.getKnowledgeBase().getRules();
+ List dataSourceDeclarations = interpreter.getKnowledgeBase().getDataSourceDeclarations();
+
+ assertTrue(facts.isEmpty());
+ assertTrue(rules.isEmpty());
+ assertEquals(Arrays.asList(dataSourceDeclaration), dataSourceDeclarations);
+ }
+
+ @Test
+ public void correctUseRemoveAll_succeeds()
+ throws ParsingException, CommandExecutionException, MalformedURLException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ Predicate predicate = Expressions.makePredicate("p", 1);
+ Predicate predicate2 = Expressions.makePredicate("q", 1);
+ DataSource dataSource = new SparqlQueryResultDataSource(new URL("http://example.org"), "?x", "?x ");
+ DataSourceDeclaration dataSourceDeclaration = new DataSourceDeclarationImpl(predicate, dataSource);
+ DataSourceDeclaration dataSourceDeclaration2 = new DataSourceDeclarationImpl(predicate2, dataSource);
+ interpreter.getKnowledgeBase().addStatement(dataSourceDeclaration);
+ interpreter.getKnowledgeBase().addStatement(dataSourceDeclaration2);
+
+ Command command = interpreter.parseCommand("@delsource p[1] .");
+ interpreter.runCommand(command);
+ List facts = interpreter.getKnowledgeBase().getFacts();
+ List rules = interpreter.getKnowledgeBase().getRules();
+ List dataSourceDeclarations = interpreter.getKnowledgeBase().getDataSourceDeclarations();
+
+ assertTrue(facts.isEmpty());
+ assertTrue(rules.isEmpty());
+ assertEquals(Arrays.asList(dataSourceDeclaration2), dataSourceDeclarations);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongFirstArgumentType_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@dellsource \"string\" p(a).");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongSecondArgumentType_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@delsource p[1]: \"string\" .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongSecondArgumentUnknownSource_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@delsource p[1]: unknown(a) .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentCount_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@delsource p[2]: p(a) p(b) .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentCountZero_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@delsource .");
+ interpreter.runCommand(command);
+ }
+
+ @Test
+ public void help_succeeds() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ CommandInterpreter commandInterpreter = new RemoveSourceCommandInterpreter();
+ InterpreterTest.checkHelpFormat(commandInterpreter, interpreter, writer);
+ }
+
+ @Test
+ public void synopsis_succeeds() throws ParsingException, CommandExecutionException {
+ CommandInterpreter commandInterpreter = new RemoveSourceCommandInterpreter();
+ InterpreterTest.checkSynopsisFormat(commandInterpreter);
+ }
+
+}
diff --git a/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/RetractCommandInterpreterTest.java b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/RetractCommandInterpreterTest.java
new file mode 100644
index 000000000..cc693eb7b
--- /dev/null
+++ b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/RetractCommandInterpreterTest.java
@@ -0,0 +1,144 @@
+package org.semanticweb.rulewerk.commands;
+
+/*-
+ * #%L
+ * Rulewerk command execution support
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import static org.junit.Assert.*;
+
+import java.io.StringWriter;
+import java.util.Arrays;
+import java.util.List;
+
+import org.junit.Test;
+import org.semanticweb.rulewerk.core.model.api.Command;
+import org.semanticweb.rulewerk.core.model.api.DataSourceDeclaration;
+import org.semanticweb.rulewerk.core.model.api.Fact;
+import org.semanticweb.rulewerk.core.model.api.PositiveLiteral;
+import org.semanticweb.rulewerk.core.model.api.Predicate;
+import org.semanticweb.rulewerk.core.model.api.Rule;
+import org.semanticweb.rulewerk.core.model.api.Term;
+import org.semanticweb.rulewerk.core.model.implementation.Expressions;
+import org.semanticweb.rulewerk.parser.ParsingException;
+
+public class RetractCommandInterpreterTest {
+
+ @Test
+ public void correctUse_succeeds() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ Term a = Expressions.makeAbstractConstant("a");
+ Term x = Expressions.makeUniversalVariable("X");
+ Predicate p = Expressions.makePredicate("p", 1);
+ Predicate q = Expressions.makePredicate("q", 1);
+ Predicate r = Expressions.makePredicate("r", 1);
+ Fact fact = Expressions.makeFact(p, a);
+ Fact fact2 = Expressions.makeFact(q, a);
+ PositiveLiteral headLiteral = Expressions.makePositiveLiteral(q, x);
+ PositiveLiteral bodyLiteral = Expressions.makePositiveLiteral(r, x);
+ Rule rule = Expressions.makeRule(headLiteral, bodyLiteral);
+ interpreter.getKnowledgeBase().addStatement(fact);
+ interpreter.getKnowledgeBase().addStatement(fact2);
+ interpreter.getKnowledgeBase().addStatement(rule);
+
+ Command command = interpreter.parseCommand("@retract p(a) q(?X) :- r(?X) .");
+ interpreter.runCommand(command);
+ List facts = interpreter.getKnowledgeBase().getFacts();
+ List rules = interpreter.getKnowledgeBase().getRules();
+ List dataSourceDeclarations = interpreter.getKnowledgeBase().getDataSourceDeclarations();
+
+ assertEquals("retract", command.getName());
+ assertEquals(2, command.getArguments().size());
+ assertTrue(command.getArguments().get(0).fromPositiveLiteral().isPresent());
+ assertTrue(command.getArguments().get(1).fromRule().isPresent());
+
+ assertEquals(Arrays.asList(fact2), facts);
+ assertTrue(rules.isEmpty());
+ assertTrue(dataSourceDeclarations.isEmpty());
+ }
+
+ @Test
+ public void correctUse_retractPredicate_succeeds() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ Term a = Expressions.makeAbstractConstant("a");
+ Term b = Expressions.makeAbstractConstant("b");
+ Predicate p = Expressions.makePredicate("p", 1);
+ Predicate q = Expressions.makePredicate("q", 1);
+ Fact pa = Expressions.makeFact(p, a);
+ Fact pb = Expressions.makeFact(p, b);
+ Fact qa = Expressions.makeFact(q, a);
+
+ interpreter.getKnowledgeBase().addStatement(pa);
+ interpreter.getKnowledgeBase().addStatement(pb);
+ interpreter.getKnowledgeBase().addStatement(qa);
+
+ Command command = interpreter.parseCommand("@retract p[1] .");
+ interpreter.runCommand(command);
+ List facts = interpreter.getKnowledgeBase().getFacts();
+ List rules = interpreter.getKnowledgeBase().getRules();
+ List dataSourceDeclarations = interpreter.getKnowledgeBase().getDataSourceDeclarations();
+
+ assertEquals(Arrays.asList(qa), facts);
+ assertTrue(rules.isEmpty());
+ assertTrue(dataSourceDeclarations.isEmpty());
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentTermNumber_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@retract 42 .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentTermStringNoPredicate_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@retract \"string\" .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentNonFact_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@retract p(?X) .");
+ interpreter.runCommand(command);
+ }
+
+ @Test
+ public void help_succeeds() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ CommandInterpreter commandInterpreter = new RetractCommandInterpreter();
+ InterpreterTest.checkHelpFormat(commandInterpreter, interpreter, writer);
+ }
+
+ @Test
+ public void synopsis_succeeds() throws ParsingException, CommandExecutionException {
+ CommandInterpreter commandInterpreter = new RetractCommandInterpreter();
+ InterpreterTest.checkSynopsisFormat(commandInterpreter);
+ }
+
+}
diff --git a/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/SetPrefixCommandInterpreterTest.java b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/SetPrefixCommandInterpreterTest.java
new file mode 100644
index 000000000..9190c8407
--- /dev/null
+++ b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/SetPrefixCommandInterpreterTest.java
@@ -0,0 +1,91 @@
+package org.semanticweb.rulewerk.commands;
+
+/*-
+ * #%L
+ * Rulewerk command execution support
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import static org.junit.Assert.*;
+
+import java.io.StringWriter;
+
+import org.junit.Test;
+import org.semanticweb.rulewerk.core.exceptions.PrefixDeclarationException;
+import org.semanticweb.rulewerk.core.model.api.Command;
+import org.semanticweb.rulewerk.parser.ParsingException;
+
+public class SetPrefixCommandInterpreterTest {
+
+ @Test
+ public void correctUse_succeeds() throws ParsingException, CommandExecutionException, PrefixDeclarationException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@setprefix eg: .");
+ interpreter.runCommand(command);
+
+ assertEquals("setprefix", command.getName());
+ assertEquals(2, command.getArguments().size());
+ assertTrue(command.getArguments().get(0).fromTerm().isPresent());
+ assertTrue(command.getArguments().get(1).fromTerm().isPresent());
+
+ assertEquals("http://example.org/", interpreter.getKnowledgeBase().getPrefixIri("eg:"));
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongFirstArgument_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@setprefix 123 .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongSecondArgument_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@setprefix pre: 123 .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentCount_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@setprefix .");
+ interpreter.runCommand(command);
+ }
+
+ @Test
+ public void help_succeeds() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ CommandInterpreter commandInterpreter = new SetPrefixCommandInterpreter();
+ InterpreterTest.checkHelpFormat(commandInterpreter, interpreter, writer);
+ }
+
+ @Test
+ public void synopsis_succeeds() throws ParsingException, CommandExecutionException {
+ CommandInterpreter commandInterpreter = new SetPrefixCommandInterpreter();
+ InterpreterTest.checkSynopsisFormat(commandInterpreter);
+ }
+
+}
diff --git a/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/ShowKbCommandInterpreterTest.java b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/ShowKbCommandInterpreterTest.java
new file mode 100644
index 000000000..5ddd3b231
--- /dev/null
+++ b/rulewerk-commands/src/test/java/org/semanticweb/rulewerk/commands/ShowKbCommandInterpreterTest.java
@@ -0,0 +1,97 @@
+package org.semanticweb.rulewerk.commands;
+
+/*-
+ * #%L
+ * Rulewerk command execution support
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import static org.junit.Assert.*;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.io.Writer;
+
+import org.junit.Test;
+import org.mockito.Mockito;
+import org.semanticweb.rulewerk.core.model.api.Command;
+import org.semanticweb.rulewerk.core.model.api.Fact;
+import org.semanticweb.rulewerk.core.model.api.Predicate;
+import org.semanticweb.rulewerk.core.model.api.Term;
+import org.semanticweb.rulewerk.core.model.implementation.Expressions;
+import org.semanticweb.rulewerk.parser.ParsingException;
+
+public class ShowKbCommandInterpreterTest {
+
+ @Test
+ public void correctUse_succeeds() throws ParsingException, CommandExecutionException, IOException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ Predicate predicate = Expressions.makePredicate("p", 1);
+ Term term = Expressions.makeAbstractConstant("a");
+ Fact fact = Expressions.makeFact(predicate, term);
+ interpreter.getKnowledgeBase().addStatement(fact);
+
+ Command command = interpreter.parseCommand("@showkb .");
+ interpreter.runCommand(command);
+
+ StringWriter anotherWriter = new StringWriter();
+ interpreter.getKnowledgeBase().writeKnowledgeBase(anotherWriter);
+
+ assertEquals("showkb", command.getName());
+ assertEquals(0, command.getArguments().size());
+ assertEquals(writer.toString(), anotherWriter.toString());
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void wrongArgumentCount_fails() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+
+ Command command = interpreter.parseCommand("@showkb p(?X) .");
+ interpreter.runCommand(command);
+ }
+
+ @Test(expected = CommandExecutionException.class)
+ public void ioError_fails() throws ParsingException, CommandExecutionException, IOException {
+ Writer writer = Mockito.mock(Writer.class);
+ Mockito.doThrow(IOException.class).when(writer).write(Mockito.anyString());
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ Predicate predicate = Expressions.makePredicate("p", 1);
+ Term term = Expressions.makeAbstractConstant("a");
+ Fact fact = Expressions.makeFact(predicate, term);
+ interpreter.getKnowledgeBase().addStatement(fact);
+
+ Command command = interpreter.parseCommand("@showkb .");
+ interpreter.runCommand(command);
+ }
+
+ @Test
+ public void help_succeeds() throws ParsingException, CommandExecutionException {
+ StringWriter writer = new StringWriter();
+ Interpreter interpreter = InterpreterTest.getMockInterpreter(writer);
+ CommandInterpreter commandInterpreter = new ShowKbCommandInterpreter();
+ InterpreterTest.checkHelpFormat(commandInterpreter, interpreter, writer);
+ }
+
+ @Test
+ public void synopsis_succeeds() throws ParsingException, CommandExecutionException {
+ CommandInterpreter commandInterpreter = new ShowKbCommandInterpreter();
+ InterpreterTest.checkSynopsisFormat(commandInterpreter);
+ }
+
+}
diff --git a/vlog4j-owlapi/LICENSE.txt b/rulewerk-core/LICENSE.txt
similarity index 100%
rename from vlog4j-owlapi/LICENSE.txt
rename to rulewerk-core/LICENSE.txt
diff --git a/rulewerk-core/pom.xml b/rulewerk-core/pom.xml
new file mode 100644
index 000000000..e647d0d75
--- /dev/null
+++ b/rulewerk-core/pom.xml
@@ -0,0 +1,18 @@
+
+
+ 4.0.0
+
+
+ org.semanticweb.rulewerk
+ rulewerk-parent
+ 0.10.0-SNAPSHOT
+
+
+ rulewerk-core
+ jar
+
+ Rulewerk Core Components
+ Core components of Rulewerk: reasoner interface and model
+
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/exceptions/IncompatiblePredicateArityException.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/exceptions/IncompatiblePredicateArityException.java
similarity index 79%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/exceptions/IncompatiblePredicateArityException.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/exceptions/IncompatiblePredicateArityException.java
index db42ff58c..57f505120 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/exceptions/IncompatiblePredicateArityException.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/exceptions/IncompatiblePredicateArityException.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.exceptions;
+package org.semanticweb.rulewerk.core.exceptions;
/*-
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,17 +22,17 @@
import java.text.MessageFormat;
-import org.semanticweb.vlog4j.core.model.api.DataSource;
-import org.semanticweb.vlog4j.core.model.api.Predicate;
+import org.semanticweb.rulewerk.core.model.api.DataSource;
+import org.semanticweb.rulewerk.core.model.api.Predicate;
/**
* Expression thrown when attempting to load facts for a {@link Predicate} from
* a {@link DataSource} that does not contain data of the specified arity.
- *
+ *
* @author Irina Dragoste
*
*/
-public class IncompatiblePredicateArityException extends VLog4jRuntimeException {
+public class IncompatiblePredicateArityException extends RulewerkRuntimeException {
private static final long serialVersionUID = -5081219042292721026L;
private static final String messagePattern = "Predicate arity [{0}] of predicate [{1}] incompatible with arity [{2}] of the data source [{3}]!";
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/exceptions/PrefixDeclarationException.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/exceptions/PrefixDeclarationException.java
similarity index 64%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/exceptions/PrefixDeclarationException.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/exceptions/PrefixDeclarationException.java
index f3806c21d..0e6515403 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/exceptions/PrefixDeclarationException.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/exceptions/PrefixDeclarationException.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.exceptions;
+package org.semanticweb.rulewerk.core.exceptions;
/*-
* #%L
- * vlog4j-parser
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 - 2019 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,13 +20,14 @@
* #L%
*/
-public class PrefixDeclarationException extends VLog4jException {
- /**
- *
- */
- private static final long serialVersionUID = 1L;
+public class PrefixDeclarationException extends RulewerkException {
+ private static final long serialVersionUID = 787997047134745982L;
public PrefixDeclarationException(String errorMessage) {
super(errorMessage);
}
+
+ public PrefixDeclarationException(String errorMessage, Throwable cause) {
+ super(errorMessage, cause);
+ }
}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/exceptions/ReasonerStateException.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/exceptions/ReasonerStateException.java
similarity index 83%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/exceptions/ReasonerStateException.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/exceptions/ReasonerStateException.java
index 7d26dbd47..d87ef7fcd 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/exceptions/ReasonerStateException.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/exceptions/ReasonerStateException.java
@@ -1,8 +1,8 @@
/*
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,20 +18,20 @@
* #L%
*/
-package org.semanticweb.vlog4j.core.exceptions;
+package org.semanticweb.rulewerk.core.exceptions;
import java.text.MessageFormat;
-import org.semanticweb.vlog4j.core.reasoner.ReasonerState;
+import org.semanticweb.rulewerk.core.reasoner.ReasonerState;
/**
* Thrown when an operation that is invalid in current reasoner state is
* attempted.
- *
+ *
* @author Irina Dragoste
*
*/
-public class ReasonerStateException extends VLog4jRuntimeException {
+public class ReasonerStateException extends RulewerkRuntimeException {
/**
* generated serial version UID
@@ -42,7 +42,7 @@ public class ReasonerStateException extends VLog4jRuntimeException {
/**
* Creates an exception with a logging message for current reasoner state.
- *
+ *
* @param state
* the current Reasoner state.
* @param message
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/exceptions/RulewerkException.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/exceptions/RulewerkException.java
new file mode 100644
index 000000000..5223c04bc
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/exceptions/RulewerkException.java
@@ -0,0 +1,50 @@
+package org.semanticweb.rulewerk.core.exceptions;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+/**
+ * Top-level checked exception for Rulewerk system.
+ * @author Irina Dragoste
+ *
+ */
+public class RulewerkException extends Exception {
+
+ /**
+ * generated serial version UID
+ */
+ private static final long serialVersionUID = 8305375071519734590L;
+
+ public RulewerkException(Throwable cause) {
+ super(cause);
+ }
+
+ public RulewerkException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+ public RulewerkException(String message) {
+ super(message);
+ }
+
+ public RulewerkException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
+}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/exceptions/VLog4jRuntimeException.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/exceptions/RulewerkRuntimeException.java
similarity index 55%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/exceptions/VLog4jRuntimeException.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/exceptions/RulewerkRuntimeException.java
index 56fd985a6..93237f788 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/exceptions/VLog4jRuntimeException.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/exceptions/RulewerkRuntimeException.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.exceptions;
+package org.semanticweb.rulewerk.core.exceptions;
/*-
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 - 2019 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,23 +21,31 @@
*/
/**
- * Superclass of unchecked exceptions generated by VLog4j.
- *
+ * Superclass of unchecked exceptions generated by Rulewerk.
+ *
* @author Markus Kroetzsch
*
*/
-public class VLog4jRuntimeException extends RuntimeException {
+public class RulewerkRuntimeException extends RuntimeException {
/**
* Generated serial version ID.
*/
private static final long serialVersionUID = -6574826887294416900L;
- public VLog4jRuntimeException(String message, Throwable cause) {
+ public RulewerkRuntimeException(Throwable cause) {
+ super(cause);
+ }
+
+ public RulewerkRuntimeException(String message, Throwable cause) {
super(message, cause);
}
- public VLog4jRuntimeException(String message) {
+ public RulewerkRuntimeException(String message) {
super(message);
}
+
+ public RulewerkRuntimeException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
+ super(message, cause, enableSuppression, writableStackTrace);
+ }
}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/reasoner/implementation/VLogDataSource.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/AbstractConstant.java
similarity index 56%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/reasoner/implementation/VLogDataSource.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/AbstractConstant.java
index 04024d3d2..5d43e7cf3 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/reasoner/implementation/VLogDataSource.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/AbstractConstant.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.reasoner.implementation;
+package org.semanticweb.rulewerk.core.model.api;
/*-
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 - 2019 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,17 +20,18 @@
* #L%
*/
-import org.semanticweb.vlog4j.core.model.api.DataSource;
-
/**
- * Abstract base class for VLog-specific data sources.
- *
- * @author Markus Kroetzsch
+ * Interface for abstract constants, i.e. for constants that represent an
+ * abstract domain element (in contrast to a specific value of a concrete
+ * datatype). Such terms are of type {@link TermType#ABSTRACT_CONSTANT}.
*
+ * @author Markus Kroetzsch
*/
-public abstract class VLogDataSource implements DataSource {
+public interface AbstractConstant extends Constant {
- public static final String PREDICATE_NAME_CONFIG_LINE = "EDB%1$d_predname=%2$s\n";
- public static final String DATASOURCE_TYPE_CONFIG_PARAM = "EDB%1$d_type";
+ @Override
+ default TermType getType() {
+ return TermType.ABSTRACT_CONSTANT;
+ }
}
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Argument.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Argument.java
new file mode 100644
index 000000000..e25136bd3
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Argument.java
@@ -0,0 +1,225 @@
+package org.semanticweb.rulewerk.core.model.api;
+
+/*-
+ * #%L
+ * Rulewerk Parser
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import java.util.Optional;
+import java.util.function.Function;
+
+/**
+ * A tagged union representing the possible types allowed to appear as arguments
+ * in commands and parser directives.
+ *
+ * @author Maximilian Marx
+ */
+public abstract class Argument {
+ private Argument() {
+ }
+
+ /**
+ * Apply a function to the contained value.
+ *
+ * @param termHandler the function to apply to a Term
+ * @param ruleHandler the function to apply to a Rule
+ * @param positiveLiteralHandler the function to apply to a Literal
+ *
+ * @return the value returned by the appropriate handler function
+ */
+ public abstract V apply(Function super Term, ? extends V> termHandler,
+ Function super Rule, ? extends V> ruleHandler,
+ Function super PositiveLiteral, ? extends V> positiveLiteralHandler);
+
+ /**
+ * Partially compare two arguments, without comparing the actual values.
+ *
+ * @param other the Object to compare to.
+ *
+ * @return An {@link Optional} containing true if the arguments are surely
+ * equal, containing false if the arguments are not equal, or an empty
+ * Optional if the values of the arguments need to be compared.
+ *
+ */
+ protected Optional isEqual(Object other) {
+ if (other == null) {
+ return Optional.of(false);
+ }
+
+ if (other == this) {
+ return Optional.of(true);
+ }
+
+ if (!(other instanceof Argument)) {
+ return Optional.of(false);
+ }
+
+ return Optional.empty();
+ }
+
+ /**
+ * Create an argument containing a Term.
+ *
+ * @param value the Term value
+ *
+ * @return An argument containing the given Term value
+ */
+ public static Argument term(Term value) {
+ return new Argument() {
+ @Override
+ public V apply(Function super Term, ? extends V> termHandler,
+ Function super Rule, ? extends V> ruleHandler,
+ Function super PositiveLiteral, ? extends V> positiveLiteralHandler) {
+ return termHandler.apply(value);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ Optional maybeEquals = isEqual(other);
+
+ if (maybeEquals.isPresent()) {
+ return maybeEquals.get();
+ }
+
+ Argument otherArgument = (Argument) other;
+ return otherArgument.apply(term -> term.equals(value), rule -> false, positiveLiteral -> false);
+ }
+
+ @Override
+ public int hashCode() {
+ return 47 * value.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return value.toString();
+ }
+ };
+ }
+
+ /**
+ * Create an argument containing a Rule.
+ *
+ * @param value the Rule value
+ *
+ * @return An argument containing the given Rule value
+ */
+ public static Argument rule(Rule value) {
+ return new Argument() {
+ @Override
+ public V apply(Function super Term, ? extends V> termHandler,
+ Function super Rule, ? extends V> ruleHandler,
+ Function super PositiveLiteral, ? extends V> positiveLiteralHandler) {
+ return ruleHandler.apply(value);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ Optional maybeEquals = isEqual(other);
+
+ if (maybeEquals.isPresent()) {
+ return maybeEquals.get();
+ }
+
+ Argument otherArgument = (Argument) other;
+ return otherArgument.apply(term -> false, rule -> rule.equals(value), positiveLiteral -> false);
+ }
+
+ @Override
+ public int hashCode() {
+ return 53 * value.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return value.toString();
+ }
+ };
+ }
+
+ /**
+ * Create an argument containing a PositiveLiteral.
+ *
+ * @param value the PositiveLiteral value
+ *
+ * @return An argument containing the given PositiveLiteral value
+ */
+ public static Argument positiveLiteral(PositiveLiteral value) {
+ return new Argument() {
+ @Override
+ public V apply(Function super Term, ? extends V> termHandler,
+ Function super Rule, ? extends V> ruleHandler,
+ Function super PositiveLiteral, ? extends V> positiveLiteralHandler) {
+ return positiveLiteralHandler.apply(value);
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ Optional maybeEquals = isEqual(other);
+
+ if (maybeEquals.isPresent()) {
+ return maybeEquals.get();
+ }
+
+ Argument otherArgument = (Argument) other;
+ return otherArgument.apply(term -> false, rule -> false,
+ positiveLiteral -> positiveLiteral.equals(value));
+ }
+
+ @Override
+ public int hashCode() {
+ return 59 * value.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return value.toString();
+ }
+ };
+ }
+
+ /**
+ * Create an optional from a (possible) Term value.
+ *
+ * @return An optional containing the contained Term, or an empty Optional if
+ * the argument doesn't contain a Term.
+ */
+ public Optional fromTerm() {
+ return this.apply(Optional::of, value -> Optional.empty(), value -> Optional.empty());
+ }
+
+ /**
+ * Create an optional from a (possible) Rule value.
+ *
+ * @return An optional containing the contained Rule, or an empty Optional if
+ * the argument doesn't contain a Rule.
+ */
+ public Optional fromRule() {
+ return this.apply(value -> Optional.empty(), Optional::of, value -> Optional.empty());
+ }
+
+ /**
+ * Create an optional from a (possible) PositiveLiteral value.
+ *
+ * @return An optional containing the contained PositiveLiteral, or an empty
+ * Optional if the argument doesn't contain a PositiveLitreal.
+ */
+ public Optional fromPositiveLiteral() {
+ return this.apply(value -> Optional.empty(), value -> Optional.empty(), Optional::of);
+ }
+}
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Command.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Command.java
new file mode 100644
index 000000000..5240358ad
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Command.java
@@ -0,0 +1,72 @@
+package org.semanticweb.rulewerk.core.model.api;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import java.util.List;
+
+import org.semanticweb.rulewerk.core.model.implementation.Serializer;
+
+/**
+ * Class for representing a generic command that can be executed.
+ *
+ * @author Markus Kroetzsch
+ *
+ */
+public class Command implements Entity {
+
+ final String name;
+ final List arguments;
+
+ /**
+ * Constructor
+ *
+ * @param name String name of the command
+ * @param arguments list of arguments of the command
+ */
+ public Command(String name, List arguments) {
+ this.name = name;
+ this.arguments = arguments;
+ }
+
+ /**
+ * Returns the command name.
+ *
+ * @return
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * Returns the command arguments.
+ *
+ * @return
+ */
+ public List getArguments() {
+ return arguments;
+ }
+
+ @Override
+ public String toString() {
+ return Serializer.getSerialization(serializer -> serializer.writeCommand(this));
+ }
+
+}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Conjunction.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Conjunction.java
similarity index 55%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Conjunction.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Conjunction.java
index 4bb42bbef..f7b8b760f 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Conjunction.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Conjunction.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.model.api;
+package org.semanticweb.rulewerk.core.model.api;
/*-
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 - 2019 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,18 +21,17 @@
*/
import java.util.List;
-import java.util.Set;
/**
* Interface for representing conjunctions of {@link Literal}s, i.e., lists of
- * (negated or positive) atomic formulas that are connected with logical AND. Conjunctions may have
- * free variables, since they contain no quantifiers.
+ * (negated or positive) atomic formulas that are connected with logical AND.
+ * Conjunctions may have free variables, since they contain no quantifiers.
*
* @author Markus Krötzsch
*
*/
-public interface Conjunction extends Iterable {
-
+public interface Conjunction extends Iterable, SyntaxObject {
+
/**
* Returns the list of literals that are part of this conjunction.
*
@@ -40,27 +39,4 @@ public interface Conjunction extends Iterable {
*/
List getLiterals();
- /**
- * Returns the set of terms of a certain type that occur in this conjunction.
- *
- * @param termType
- * the type of the term requested
- * @return set of matching terms used in this conjunction
- */
- Set extends Term> getTerms(TermType termType);
-
- /**
- * Returns the set of all terms that occur in this conjunction.
- *
- * @return set of terms used in this conjunction
- */
- Set getTerms();
-
- /**
- * Returns the {@link Variable}s that occur in this conjunction.
- *
- * @return a set of variables
- */
- Set getVariables();
-
}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Constant.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Constant.java
similarity index 71%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Constant.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Constant.java
index 09d8c38eb..bf04acd88 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Constant.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Constant.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.model.api;
+package org.semanticweb.rulewerk.core.model.api;
/*
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,13 +21,11 @@
*/
/**
- * Interface for constants, i.e., terms of type {@link TermType#CONSTANT}.
- * Domain elements that are denoted by constants are commonly known as named
- * elements.
+ * Interface for constants, i.e. for syntactic names that refer to domain
+ * elements.
*
* @author david.carral@tu-dresden.de
* @author Markus Krötzsch
*/
public interface Constant extends Term {
}
-
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/DataSource.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/DataSource.java
new file mode 100644
index 000000000..f8afe3ee8
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/DataSource.java
@@ -0,0 +1,52 @@
+package org.semanticweb.rulewerk.core.model.api;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import java.util.Optional;
+
+/**
+ * Interfaces various types of data sources for storing facts.
+ *
+ * @author Irina Dragoste
+ *
+ */
+public interface DataSource extends Entity {
+
+ /**
+ * Retrieve the required arity of target predicates for the data source.
+ *
+ * @return the required arity for the data source, or Optional.empty() if there
+ * is none.
+ */
+ public default Optional getRequiredArity() {
+ return Optional.empty();
+ }
+
+ /**
+ * Returns a fact that represents the declaration of this {@link DataSource}.
+ * Rulewerk syntax uses facts to specify the relevant parameters for data source
+ * declarations.
+ *
+ * @return {@link Fact} that contains the parameters of this data source
+ */
+ public Fact getDeclarationFact();
+
+}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/DataSourceDeclaration.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/DataSourceDeclaration.java
similarity index 89%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/DataSourceDeclaration.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/DataSourceDeclaration.java
index 58bea5785..22efc0aae 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/DataSourceDeclaration.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/DataSourceDeclaration.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.model.api;
+package org.semanticweb.rulewerk.core.model.api;
/*-
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 - 2019 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -42,4 +42,5 @@ public interface DataSourceDeclaration extends Statement {
* @return data source specification
*/
DataSource getDataSource();
+
}
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/DatatypeConstant.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/DatatypeConstant.java
new file mode 100644
index 000000000..c64955d35
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/DatatypeConstant.java
@@ -0,0 +1,75 @@
+package org.semanticweb.rulewerk.core.model.api;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+/**
+ * Interface for datatype constants, i.e. for constants that represent a
+ * specific value of a concrete datatype). Such terms are of type
+ * {@link TermType#DATATYPE_CONSTANT}.
+ *
+ * Note that datatype literal is a common name of the representation of
+ * specific values for a datatype. We mostly avoid this meaning of
+ * literal since a literal in logic is typically a negated or non-negated
+ * atom.
+ *
+ * @author Markus Kroetzsch
+ */
+public interface DatatypeConstant extends Constant {
+
+ @Override
+ default TermType getType() {
+ return TermType.DATATYPE_CONSTANT;
+ }
+
+ /**
+ * Returns the datatype of this term, which is typically an IRI that defines how
+ * to interpret the lexical value.
+ *
+ * @return a non-blank String (not null, nor empty or whitespace).
+ */
+ String getDatatype();
+
+ /**
+ * Returns the lexical value of the data value, i.e. a string that encodes a
+ * specific value based on the value's datatype. Note that there can be several
+ * strings that represent the same value, depending on the rules of the
+ * datatype, and that there the value used here does not have to be a canonical
+ * representation.
+ *
+ * @return a non-null string
+ */
+ String getLexicalValue();
+
+ /**
+ * Returns a string representation of this value that conforms to RDF
+ * serialisation formats such as Turtle. Turtle supports some abbreviations for
+ * common types, e.g., by leaving the type away for xsd:string literals, which
+ * can be enabled or disabled through the functions parameter.
+ *
+ * @param useAbbreviations if true, the result may use Turtle-style
+ * abbreviations to shorten the output where supported;
+ * otherwise the literal will always be serialised in
+ * full
+ * @return RDF-style string serialisation of the value
+ */
+ String getRdfLiteralString(boolean useAbbreviations);
+
+}
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Entity.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Entity.java
new file mode 100644
index 000000000..75c40aa3d
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Entity.java
@@ -0,0 +1,29 @@
+package org.semanticweb.rulewerk.core.model.api;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+/**
+ * Most general type of syntactic entity in Rulewerk.
+ *
+ */
+public interface Entity {
+
+}
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/ExistentialVariable.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/ExistentialVariable.java
new file mode 100644
index 000000000..1b47a54c7
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/ExistentialVariable.java
@@ -0,0 +1,36 @@
+package org.semanticweb.rulewerk.core.model.api;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+/**
+ * Interface for existentially quantified variables, i.e., variables that appear
+ * in the scope of an (implicit) existential quantifier in a rule.
+ *
+ * @author Markus Krötzsch
+ */
+public interface ExistentialVariable extends Variable {
+
+ @Override
+ default TermType getType() {
+ return TermType.EXISTENTIAL_VARIABLE;
+ }
+
+}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Fact.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Fact.java
similarity index 86%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Fact.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Fact.java
index d9943f75e..d3b938897 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Fact.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Fact.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.model.api;
+package org.semanticweb.rulewerk.core.model.api;
/*-
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 - 2019 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/LanguageStringConstant.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/LanguageStringConstant.java
new file mode 100644
index 000000000..e19bf3517
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/LanguageStringConstant.java
@@ -0,0 +1,64 @@
+package org.semanticweb.rulewerk.core.model.api;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+/**
+ * Interface for string constants with a language tag, used to represent values
+ * of type http://www.w3.org/1999/02/22-rdf-syntax-ns#langString in RDF, OWL,
+ * and related languages used with knowledge graphs. Such terms are of type
+ * {@link TermType#LANGSTRING_CONSTANT}.
+ *
+ * @author Markus Kroetzsch
+ */
+public interface LanguageStringConstant extends Constant {
+
+ @Override
+ default TermType getType() {
+ return TermType.LANGSTRING_CONSTANT;
+ }
+
+ /**
+ * Returns the datatype of this term, which is always
+ * http://www.w3.org/1999/02/22-rdf-syntax-ns#langString.
+ *
+ * @return a IRI of RDF langString datatype
+ */
+ default String getDatatype() {
+ return PrefixDeclarationRegistry.RDF_LANGSTRING;
+ }
+
+ /**
+ * Returns the string value of the literal without the language tag.
+ *
+ * @return a non-null string
+ */
+ String getString();
+
+ /**
+ * Returns the language tag of the literal, which should be a lowercase string
+ * that conforms to the BCP 47
+ * specification.
+ *
+ * @return a non-empty string
+ */
+ String getLanguageTag();
+
+}
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Literal.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Literal.java
new file mode 100644
index 000000000..b345b070d
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Literal.java
@@ -0,0 +1,53 @@
+package org.semanticweb.rulewerk.core.model.api;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import java.util.List;
+
+/**
+ * Interface for literals. A positive literal is simply an atomic formula, i.e.,
+ * a formula of the form P(t1,...,tn) where P is a {@link Predicate} of arity n
+ * and t1,...,tn are {@link Term}s. A negative literal is a negated atomic
+ * formula.
+ *
+ * @author david.carral@tu-dresden.de
+ * @author Irina Dragoste
+ */
+public interface Literal extends SyntaxObject {
+
+ boolean isNegated();
+
+ /**
+ * The literal predicate.
+ *
+ * @return the literal predicate.
+ */
+ Predicate getPredicate();
+
+ /**
+ * The list of terms representing the tuple arguments.
+ *
+ * @return an unmodifiable list of terms with the same size as the
+ * {@link Predicate} arity.
+ */
+ List getArguments();
+
+}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Blank.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/NamedNull.java
similarity index 70%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Blank.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/NamedNull.java
index 5cd7d1803..c4f6354cb 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Blank.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/NamedNull.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.model.api;
+package org.semanticweb.rulewerk.core.model.api;
/*
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,12 +21,17 @@
*/
/**
- * Interface for {@link TermType#BLANK} terms. A blank is an entity used to
+ * Interface for {@link TermType#NAMED_NULL} terms. A blank is an entity used to
* represent anonymous domain elements introduced during the reasoning process
* to satisfy existential restrictions.
*
* @author david.carral@tu-dresden.de
*/
-public interface Blank extends Term {
-}
+public interface NamedNull extends Term {
+
+ @Override
+ default TermType getType() {
+ return TermType.NAMED_NULL;
+ }
+}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/NegativeLiteral.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/NegativeLiteral.java
similarity index 84%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/NegativeLiteral.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/NegativeLiteral.java
index 1321d77c7..df5c6e6b0 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/NegativeLiteral.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/NegativeLiteral.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.model.api;
+package org.semanticweb.rulewerk.core.model.api;
/*-
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 - 2019 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/PositiveLiteral.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/PositiveLiteral.java
similarity index 84%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/PositiveLiteral.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/PositiveLiteral.java
index 90c5f770f..6c4598a77 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/PositiveLiteral.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/PositiveLiteral.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.model.api;
+package org.semanticweb.rulewerk.core.model.api;
/*-
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 - 2019 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Predicate.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Predicate.java
similarity index 86%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Predicate.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Predicate.java
index aaa126fa6..7ed7d48f8 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Predicate.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Predicate.java
@@ -1,50 +1,49 @@
-package org.semanticweb.vlog4j.core.model.api;
-
-/*-
- * #%L
- * VLog4j Core Components
- * %%
- * Copyright (C) 2018 VLog4j Developers
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * #L%
- */
-
-/**
- * A Predicate represents a relation between terms. Is uniquely identified by
- * its name and arity. The arity determines the number of terms allowed in the
- * relation. For example, a Predicate with name {@code P} and arity {@code n}
- * allows atomic formulae of the form {@code P(t1,...,tn)}.
- *
- * @author Irina Dragoste
- *
- */
-public interface Predicate {
-
- /**
- * The name of the Predicate.
- *
- * @return the name of the Predicate.
- */
- String getName();
-
- /**
- * The arity represents the number of terms allowed as relation arguments for
- * this Predicate. For example, a Predicate with name {@code P} and arity
- * {@code n} allows atomic formulae of the form {@code P(t1,...,tn)}.
- *
- * @return the arity of the Predicate.
- */
- int getArity();
-
-}
+package org.semanticweb.rulewerk.core.model.api;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+/**
+ * A Predicate represents a relation between terms. Is uniquely identified by
+ * its name and arity. The arity determines the number of terms allowed in the
+ * relation. For example, a Predicate with name {@code P} and arity {@code n}
+ * allows atomic formulae of the form {@code P(t1,...,tn)}.
+ *
+ * @author Irina Dragoste
+ *
+ */
+public interface Predicate extends Entity {
+
+ /**
+ * The name of the Predicate.
+ *
+ * @return the name of the Predicate.
+ */
+ String getName();
+
+ /**
+ * The arity represents the number of terms allowed as relation arguments for
+ * this Predicate. For example, a Predicate with name {@code P} and arity
+ * {@code n} allows atomic formulae of the form {@code P(t1,...,tn)}.
+ *
+ * @return the arity of the Predicate.
+ */
+ int getArity();
+}
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/PrefixDeclarationRegistry.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/PrefixDeclarationRegistry.java
new file mode 100644
index 000000000..1532c706c
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/PrefixDeclarationRegistry.java
@@ -0,0 +1,138 @@
+package org.semanticweb.rulewerk.core.model.api;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import java.util.Map.Entry;
+
+import org.semanticweb.rulewerk.core.exceptions.PrefixDeclarationException;
+
+/**
+ * Registry that manages prefixes and base namespace declarations as used for
+ * parsing and serialising inputs.
+ *
+ * @author Markus Kroetzsch
+ */
+public interface PrefixDeclarationRegistry extends Iterable> {
+
+ static final String XSD = "http://www.w3.org/2001/XMLSchema#";
+ static final String XSD_STRING = "http://www.w3.org/2001/XMLSchema#string";
+ static final String XSD_DECIMAL = "http://www.w3.org/2001/XMLSchema#decimal";
+ static final String XSD_DOUBLE = "http://www.w3.org/2001/XMLSchema#double";
+ static final String XSD_FLOAT = "http://www.w3.org/2001/XMLSchema#float";
+ static final String XSD_INTEGER = "http://www.w3.org/2001/XMLSchema#integer";
+ static final String XSD_INT = "http://www.w3.org/2001/XMLSchema#int";
+ static final String XSD_LONG = "http://www.w3.org/2001/XMLSchema#long";
+ static final String XSD_SHORT = "http://www.w3.org/2001/XMLSchema#short";
+ static final String XSD_BYTE = "http://www.w3.org/2001/XMLSchema#byte";
+ static final String XSD_BOOLEAN = "http://www.w3.org/2001/XMLSchema#boolean";
+ static final String RDF_LANGSTRING = "http://www.w3.org/1999/02/22-rdf-syntax-ns#langString";
+
+ static final String RDF = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+ static final String RDF_TYPE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
+
+ static final String EMPTY_BASE = "";
+ static final String PREFIX_NAME_SEPARATOR = ":";
+
+ /**
+ * Resets the registry to an empty state, without a base or any prefixes.
+ */
+ void clear();
+
+ /**
+ * Returns the relevant base namespace. This should always return a result,
+ * possibly using a local default value if no base was declared.
+ *
+ * @return string of an absolute base IRI
+ */
+ String getBaseIri();
+
+ /**
+ * Sets the base namespace to the given value. This should only be done once,
+ * and not after the base namespace was assumed to be an implicit default value.
+ *
+ * @param baseIri the new base namespace
+ * @throws PrefixDeclarationException if base was already defined
+ */
+ void setBaseIri(String baseIri) throws PrefixDeclarationException;
+
+ /**
+ * Returns the IRI associated with a given prefix name.
+ *
+ * @param prefixName the name of the prefix.
+ * @throws PrefixDeclarationException if prefixName was not defined.
+ */
+ String getPrefixIri(String prefixName) throws PrefixDeclarationException;
+
+ /**
+ * Registers a prefix declaration. Behaviour is implementation-defined if
+ * prefixName has already been registered.
+ *
+ * @param prefixName the name of the prefix.
+ * @param prefixIri the IRI of the prefix.
+ *
+ * @throws PrefixDeclarationException when prefixName is already registered, at
+ * the discretion of the implementation.
+ */
+ void setPrefixIri(String prefixName, String prefixIri) throws PrefixDeclarationException;
+
+ /**
+ * Un-registers a prefix declaration if present.
+ *
+ * @param prefixName the name of the prefix.
+ */
+ void unsetPrefix(String prefixName);
+
+ /**
+ * Turn a prefixed
+ * name into an absolute IRI.
+ *
+ * @param prefixedName a prefixed name of the form prefixName:localName.
+ *
+ * @throws PrefixDeclarationException when the prefixName has not been declared.
+ * @return an absolute IRI corresponding to prefixedName.
+ */
+ String resolvePrefixedName(String prefixedName) throws PrefixDeclarationException;
+
+ /**
+ * Turn a potentially relative IRI into an absolute IRI.
+ *
+ * @param relativeOrAbsoluteIri an IRI that may be relative or absolute.
+ * @throws PrefixDeclarationException when relativeOrAbsoluteIri is not a valid
+ * IRI.
+ *
+ * @return when relativeOrAbsoluteIri is an absolute IRI, it is returned as-is.
+ * Otherwise, the current base IRI is prepended.
+ */
+ String absolutizeIri(String relativeOrAbsoluteIri) throws PrefixDeclarationException;
+
+ /**
+ * Turn an absolute IRI into a (possibly) prefixed name. Dual to
+ * {@link PrefixDeclarationRegistry#resolvePrefixedName}.
+ *
+ * @param iri an absolute IRI to abbreviate
+ * @param addIriBrackets if true, unabbreviated IRIs will be enclosed in <
+ * >
+ *
+ * @return an abbreviated form of {@code iri} if an appropriate prefix is known,
+ * or {@code iri}.
+ */
+ String unresolveAbsoluteIri(String iri, boolean addIriBrackets);
+}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/QueryResult.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/QueryResult.java
similarity index 87%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/QueryResult.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/QueryResult.java
index 0ea7e1f8e..49c6319b7 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/QueryResult.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/QueryResult.java
@@ -1,43 +1,43 @@
-package org.semanticweb.vlog4j.core.model.api;
-
-/*-
- * #%L
- * VLog4j Core Components
- * %%
- * Copyright (C) 2018 VLog4j Developers
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * #L%
- */
-
-import java.util.List;
-
-/**
- * A Query Result represents a list of terms that match the terms of the asked
- * query. The terms can be named individuals (constants) and anonymous
- * individuals (blanks).
- *
- * @author Irina Dragoste
- *
- */
-public interface QueryResult {
-
- /**
- * Getter for the terms that represent a query answer.
- *
- * @return the terms that represent a query answer. They can be named
- * individuals (constants) and anonymous individuals (blanks).
- */
- List getTerms();
-
-}
+package org.semanticweb.rulewerk.core.model.api;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import java.util.List;
+
+/**
+ * A Query Result represents a list of terms that match the terms of the asked
+ * query. The terms can be named individuals (constants) and anonymous
+ * individuals (blanks).
+ *
+ * @author Irina Dragoste
+ *
+ */
+public interface QueryResult {
+
+ /**
+ * Getter for the terms that represent a query answer.
+ *
+ * @return the terms that represent a query answer. They can be named
+ * individuals (constants) and anonymous individuals (blanks).
+ */
+ List getTerms();
+
+}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Rule.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Rule.java
similarity index 60%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Rule.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Rule.java
index 1417dfab8..9187282eb 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Rule.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Rule.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.model.api;
+package org.semanticweb.rulewerk.core.model.api;
/*-
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 - 2019 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,20 +20,18 @@
* #L%
*/
-import java.util.Set;
-
/**
* Interface for classes representing a rule. This implementation assumes that
- * rules are defined by their head and body literals, without explicitly specifying
- * quantifiers. All variables in the body are considered universally quantified;
- * all variables in the head that do not occur in the body are considered
- * existentially quantified.
+ * rules are defined by their head and body literals, without explicitly
+ * specifying quantifiers. All variables in the body are considered universally
+ * quantified; all variables in the head that do not occur in the body are
+ * considered existentially quantified.
*
* @author Markus Krötzsch
*
*/
-public interface Rule extends Statement {
-
+public interface Rule extends SyntaxObject, Statement {
+
/**
* Returns the conjunction of head literals (the consequence of the rule).
*
@@ -48,18 +46,4 @@ public interface Rule extends Statement {
*/
Conjunction getBody();
- /**
- * Returns the existentially quantified head variables of this rule.
- *
- * @return a set of variables
- */
- Set getExistentiallyQuantifiedVariables();
-
- /**
- * Returns the universally quantified variables of this rule.
- *
- * @return a set of variables
- */
- Set getUniversallyQuantifiedVariables();
-
}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Statement.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Statement.java
similarity index 85%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Statement.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Statement.java
index 464397b18..f43c03248 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Statement.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Statement.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.model.api;
+package org.semanticweb.rulewerk.core.model.api;
/*-
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 - 2019 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@
* @author Markus Kroetzsch
*
*/
-public interface Statement {
+public interface Statement extends Entity {
/**
* Accept a {@link StatementVisitor} and return its output.
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/StatementVisitor.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/StatementVisitor.java
similarity index 91%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/StatementVisitor.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/StatementVisitor.java
index fc556f18e..5e8f308f6 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/StatementVisitor.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/StatementVisitor.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.model.api;
+package org.semanticweb.rulewerk.core.model.api;
/*-
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 - 2019 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/SyntaxObject.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/SyntaxObject.java
new file mode 100644
index 000000000..7dcf50142
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/SyntaxObject.java
@@ -0,0 +1,105 @@
+package org.semanticweb.rulewerk.core.model.api;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import java.util.stream.Stream;
+
+/**
+ * General interface for all classes that represent syntactic objects that might
+ * contain atomic terms, in particular all kinds of logical formulas. Compound
+ * terms (with nested functions) would also be of this type if we had them.
+ *
+ * @author Markus Kroetzsch
+ *
+ */
+public interface SyntaxObject extends Entity {
+
+ /**
+ * Returns the stream of distinct terms that occur in this object.
+ *
+ * @return stream of distinct terms used in this object
+ */
+ Stream getTerms();
+
+ /**
+ * Return the stream of distinct universal variables in this object.
+ *
+ * @return stream of universal variables
+ */
+ default Stream getUniversalVariables() {
+ return Terms.getUniversalVariables(getTerms());
+ }
+
+ /**
+ * Return the stream of distinct existential variables in this object.
+ *
+ * @return stream of existential variables
+ */
+ default Stream getExistentialVariables() {
+ return Terms.getExistentialVariables(getTerms());
+ }
+
+ /**
+ * Return the stream of distinct variables in this object.
+ *
+ * @return stream of variables
+ */
+ default Stream getVariables() {
+ return Terms.getVariables(getTerms());
+ }
+
+ /**
+ * Return the stream of distinct constants in this object.
+ *
+ * @return stream of constants
+ */
+ default Stream getConstants() {
+ return Terms.getConstants(getTerms());
+ }
+
+ /**
+ * Return the stream of distinct abstract constants in this object.
+ *
+ * @return stream of abstract constants
+ */
+ default Stream getAbstractConstants() {
+ return Terms.getAbstractConstants(getTerms());
+ }
+
+ /**
+ * Return the stream of distinct datatype constants in this object.
+ *
+ * @return stream of datatype constants
+ */
+ default Stream getDatatypeConstants() {
+ return Terms.getDatatypeConstants(getTerms());
+ }
+
+ /**
+ * Return the stream of distinct named nulls in this object.
+ *
+ * @return stream of named nulls
+ */
+ default Stream getNamedNulls() {
+ return Terms.getNamedNulls(getTerms());
+ }
+
+}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Term.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Term.java
similarity index 59%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Term.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Term.java
index 898c41c7c..bb0be440d 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Term.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Term.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.model.api;
+package org.semanticweb.rulewerk.core.model.api;
/*
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,28 +27,47 @@
* @author david.carral@tu-dresden.de
* @author Markus Krötzsch
*/
-public interface Term {
+public interface Term extends Entity {
/**
* Returns the name this term. The name uniquely identifies terms of the same
* {@link TermType}.
- *
+ *
* @return a non-blank String (not null, nor empty or whitespace).
*/
String getName();
/**
* Return the type of this term.
- *
+ *
* @return the type of this term
*/
TermType getType();
/**
- * Accept a {@link TermVisitor} and return its output.
+ * Returns true if the term represents some kind of constant.
+ *
+ * @return true if term is constant
+ */
+ default boolean isConstant() {
+ return this.getType() == TermType.ABSTRACT_CONSTANT || this.getType() == TermType.DATATYPE_CONSTANT
+ || this.getType() == TermType.LANGSTRING_CONSTANT;
+ }
+
+ /**
+ * Returns true if the term represents some kind of variable.
*
- * @param termVisitor
- * the TermVisitor
+ * @return true if term is variable
+ */
+ default boolean isVariable() {
+ return this.getType() == TermType.UNIVERSAL_VARIABLE || this.getType() == TermType.EXISTENTIAL_VARIABLE;
+ }
+
+ /**
+ * Accept a {@link TermVisitor} and return its output.
+ *
+ * @param termVisitor the TermVisitor
+ * @param type associated to the given TermVisitor
* @return output of the visitor
*/
T accept(TermVisitor termVisitor);
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/TermType.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/TermType.java
new file mode 100644
index 000000000..490604400
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/TermType.java
@@ -0,0 +1,62 @@
+package org.semanticweb.rulewerk.core.model.api;
+
+/*
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+/**
+ * Enumeration listing the different types of terms.
+ *
+ * @author david.carral@tu-dresden.de
+ * @author Markus Kroetzsch
+ *
+ */
+public enum TermType {
+ /**
+ * An abstract constant is a term used to represent named domain elements that
+ * are not a value of any specific datatype.
+ */
+ ABSTRACT_CONSTANT,
+ /**
+ * A datatype constant is a term used to represent named domain elements that
+ * are the value of a specific datatype.
+ */
+ DATATYPE_CONSTANT,
+ /**
+ * A string constant with a language tag, used to represent values of type
+ * http://www.w3.org/1999/02/22-rdf-syntax-ns#langString in RDF, OWL, and
+ * related languages used with knowledge graphs.
+ */
+ LANGSTRING_CONSTANT,
+ /**
+ * A named null is an entity used to represent anonymous domain elements
+ * introduced during the reasoning process to satisfy existential restrictions.
+ */
+ NAMED_NULL,
+ /**
+ * A universal variable is a variable that can only be used in positions where
+ * it is universally quantified, or implicitly assumed to be.
+ */
+ UNIVERSAL_VARIABLE,
+ /**
+ * An existential variable is a variable that can only be used in positions
+ * where it is existentially quantified, or implicitly assumed to be.
+ */
+ EXISTENTIAL_VARIABLE
+}
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/TermVisitor.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/TermVisitor.java
new file mode 100644
index 000000000..36d662321
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/TermVisitor.java
@@ -0,0 +1,79 @@
+package org.semanticweb.rulewerk.core.model.api;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+/**
+ * A visitor for the various types of {@link Term}s in the data model. Should be
+ * used to avoid any type casting or {@code instanceof} checks when processing
+ * terms.
+ *
+ * @author Markus Krötzsch
+ */
+public interface TermVisitor {
+
+ /**
+ * Visits an {@link AbstractConstant} and returns a result.
+ *
+ * @param term the term to visit
+ * @return some result
+ */
+ T visit(AbstractConstant term);
+
+ /**
+ * Visits a {@link DatatypeConstant} and returns a result.
+ *
+ * @param term the term to visit
+ * @return some result
+ */
+ T visit(DatatypeConstant term);
+
+ /**
+ * Visits a {@link LanguageStringConstant} and returns a result.
+ *
+ * @param term the term to visit
+ * @return some result
+ */
+ T visit(LanguageStringConstant term);
+
+ /**
+ * Visits a {@link UniversalVariable} and returns a result
+ *
+ * @param term the term to visit
+ * @return some result
+ */
+ T visit(UniversalVariable term);
+
+ /**
+ * Visits a {@link ExistentialVariable} and returns a result
+ *
+ * @param term the term to visit
+ * @return some result
+ */
+ T visit(ExistentialVariable term);
+
+ /**
+ * Visits a {@link NamedNull} and returns a result
+ *
+ * @param term the term to visit
+ * @return some result
+ */
+ T visit(NamedNull term);
+}
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Terms.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Terms.java
new file mode 100644
index 000000000..8e8e05ac2
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Terms.java
@@ -0,0 +1,211 @@
+package org.semanticweb.rulewerk.core.model.api;
+
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import java.util.stream.Stream;
+
+/**
+ * Collection of utility methods for handling {@link Term}s.
+ *
+ * @author Markus Kroetzsch
+ *
+ */
+public class Terms {
+
+ /**
+ * Returns a stream of variables found in the given stream of terms. Ordering
+ * and duplicates are not affected.
+ *
+ * @param terms stream of all terms
+ * @return stream of results
+ */
+ public static Stream getVariables(Stream extends Term> terms) {
+ return terms.filter(term -> term.isVariable()).map(Variable.class::cast);
+ }
+
+ /**
+ * Returns a stream of constants found in the given stream of terms. Ordering
+ * and duplicates are not affected.
+ *
+ * @param terms stream of all terms
+ * @return stream of results
+ */
+ public static Stream getConstants(Stream extends Term> terms) {
+ return terms.filter(term -> term.isConstant()).map(Constant.class::cast);
+ }
+
+ /**
+ * Returns a stream of named nulls found in the given stream of terms. Ordering
+ * and duplicates are not affected.
+ *
+ * @param terms stream of all terms
+ * @return stream of results
+ */
+ public static Stream getNamedNulls(Stream extends Term> terms) {
+ return terms.filter(term -> term.getType() == TermType.NAMED_NULL).map(NamedNull.class::cast);
+ }
+
+ /**
+ * Returns a stream of universal variables found in the given stream of terms.
+ * Ordering and duplicates are not affected.
+ *
+ * @param terms stream of all terms
+ * @return stream of results
+ */
+ public static Stream getUniversalVariables(Stream extends Term> terms) {
+ return terms.filter(term -> term.getType() == TermType.UNIVERSAL_VARIABLE).map(UniversalVariable.class::cast);
+ }
+
+ /**
+ * Returns a stream of existential variables found in the given stream of terms.
+ * Ordering and duplicates are not affected.
+ *
+ * @param terms stream of all terms
+ * @return stream of results
+ */
+ public static Stream getExistentialVariables(Stream extends Term> terms) {
+ return terms.filter(term -> term.getType() == TermType.EXISTENTIAL_VARIABLE)
+ .map(ExistentialVariable.class::cast);
+ }
+
+ /**
+ * Returns a stream of abstract constants found in the given stream of terms.
+ * Ordering and duplicates are not affected.
+ *
+ * @param terms stream of all terms
+ * @return stream of results
+ */
+ public static Stream getAbstractConstants(Stream terms) {
+ return terms.filter(term -> term.getType() == TermType.ABSTRACT_CONSTANT).map(AbstractConstant.class::cast);
+ }
+
+ /**
+ * Returns a stream of datatype constants found in the given stream of terms.
+ * Ordering and duplicates are not affected.
+ *
+ * @param terms stream of all terms
+ * @return stream of results
+ */
+ public static Stream getDatatypeConstants(Stream terms) {
+ return terms.filter(term -> term.getType() == TermType.DATATYPE_CONSTANT).map(DatatypeConstant.class::cast);
+ }
+
+ /**
+ * Returns the lexical value of a term that is an xsd:string constant, and
+ * throws an exception for all other cases.
+ *
+ * @param term the term from which the string is to be extracted
+ * @return extracted string
+ * @throws IllegalArgumentException if the given term is not a constant of type
+ * xsd:string
+ */
+ public static String extractString(Term term) {
+ if (term.getType() == TermType.DATATYPE_CONSTANT) {
+ DatatypeConstant datatypeConstant = (DatatypeConstant) term;
+ if (PrefixDeclarationRegistry.XSD_STRING.equals(datatypeConstant.getDatatype()))
+ return datatypeConstant.getLexicalValue();
+ }
+ throw new IllegalArgumentException(
+ "Term " + term.toString() + " is not a datatype constant of type xsd:string.");
+ }
+
+ /**
+ * Returns the name of an abstract term, and throws an exception for all other
+ * cases.
+ *
+ * @param term the term from which the name is to be extracted
+ * @return extracted name
+ * @throws IllegalArgumentException if the given term is not an abstract
+ * constant
+ */
+ public static String extractName(Term term) {
+ if (term.getType() == TermType.ABSTRACT_CONSTANT) {
+ return term.getName();
+ } else {
+ throw new IllegalArgumentException("Term " + term.toString() + " is not an abstract constant.");
+ }
+ }
+
+ /**
+ * Returns the IRI representation of an abstract term, and throws an exception
+ * for all other cases.
+ *
+ * @param term the term from which the IRI is to be extracted
+ * @return extracted IRI
+ * @throws IllegalArgumentException if the given term is not an abstract
+ * constant or cannot be parsed as an IRI
+ */
+ public static URI extractIri(Term term) {
+ try {
+ return new URI(extractName(term));
+ } catch (URISyntaxException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ /**
+ * Returns the URL representation of an abstract term, and throws an exception
+ * for all other cases.
+ *
+ * @param term the term from which the URL is to be extracted
+ * @return extracted URL
+ * @throws IllegalArgumentException if the given term is not an abstract
+ * constant or cannot be parsed as a URL
+ */
+ public static URL extractUrl(Term term) {
+ try {
+ return new URL(extractName(term));
+ } catch (MalformedURLException e) {
+ throw new IllegalArgumentException(e);
+ }
+ }
+
+ /**
+ * Returns the numeric value of a term that is an xsd:integer (or supported
+ * subtype) constant, and throws an exception for all other cases.
+ *
+ * @param term the term from which the integer is to be extracted
+ * @return extracted integer
+ * @throws IllegalArgumentException if the given term is not a constant of an
+ * integer type, or if the lexical
+ * representation could not be parsed into a
+ * Java int
+ */
+ public static int extractInt(Term term) {
+ if (term.getType() == TermType.DATATYPE_CONSTANT) {
+ DatatypeConstant datatypeConstant = (DatatypeConstant) term;
+ if (PrefixDeclarationRegistry.XSD_INTEGER.equals(datatypeConstant.getDatatype())
+ || PrefixDeclarationRegistry.XSD_LONG.equals(datatypeConstant.getDatatype())
+ || PrefixDeclarationRegistry.XSD_INT.equals(datatypeConstant.getDatatype())
+ || PrefixDeclarationRegistry.XSD_SHORT.equals(datatypeConstant.getDatatype())
+ || PrefixDeclarationRegistry.XSD_BYTE.equals(datatypeConstant.getDatatype()))
+ return Integer.parseInt(datatypeConstant.getLexicalValue());
+ }
+ throw new IllegalArgumentException(
+ "Term " + term.toString() + " is not a datatype constant of a supported integer type.");
+ }
+
+}
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/UniversalVariable.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/UniversalVariable.java
new file mode 100644
index 000000000..74e95c6ae
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/UniversalVariable.java
@@ -0,0 +1,36 @@
+package org.semanticweb.rulewerk.core.model.api;
+
+/*
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+/**
+ * Interface for universally quantified variables, i.e., variables that appear
+ * in the scope of an (implicit) universal quantifier in a rule.
+ *
+ * @author Markus Krötzsch
+ */
+public interface UniversalVariable extends Variable {
+
+ @Override
+ default TermType getType() {
+ return TermType.UNIVERSAL_VARIABLE;
+ }
+
+}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Variable.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Variable.java
similarity index 65%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Variable.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Variable.java
index d6bbd59aa..c68d289c2 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/api/Variable.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/api/Variable.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.model.api;
+package org.semanticweb.rulewerk.core.model.api;
/*
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,13 +21,13 @@
*/
/**
- * Interface for variables, i.e., terms of type {@link TermType#VARIABLE}.
- * Variables are terms that can be quantified to create formulas that refer to
- * some or all values of the domain.
+ * Interface for variables, i.e., terms of type
+ * {@link TermType#UNIVERSAL_VARIABLE} and
+ * {@link TermType#EXISTENTIAL_VARIABLE}. Variables are terms that can be
+ * quantified to create formulas that refer to some or all values of the domain.
*
* @author david.carral@tu-dresden.de
* @author Markus Krötzsch
*/
public interface Variable extends Term {
}
-
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/ConstantImpl.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/AbstractConstantImpl.java
similarity index 54%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/ConstantImpl.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/AbstractConstantImpl.java
index ad4477e95..508360739 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/ConstantImpl.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/AbstractConstantImpl.java
@@ -1,21 +1,20 @@
-package org.semanticweb.vlog4j.core.model.implementation;
+package org.semanticweb.rulewerk.core.model.implementation;
-import org.semanticweb.vlog4j.core.model.api.Constant;
-import org.semanticweb.vlog4j.core.model.api.TermType;
-import org.semanticweb.vlog4j.core.model.api.TermVisitor;
+import org.semanticweb.rulewerk.core.model.api.AbstractConstant;
+import org.semanticweb.rulewerk.core.model.api.TermVisitor;
/*
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -25,35 +24,29 @@
*/
/**
- * Implements {@link Constant} terms. A constant is an entity used to represent
- * named domain elements in the domain.
+ * Implementation of {@link AbstractConstant}.
*
* @author david.carral@tu-dresden.de
*/
-public class ConstantImpl extends AbstractTermImpl implements Constant {
+public class AbstractConstantImpl extends AbstractTermImpl implements AbstractConstant {
/**
- * Instantiates a {@code ConstantImpl} object with the name {@code name}.
+ * Instantiates a {@code ConstantImpl} object with the name
+ * {@code name}.
*
- * @param name
- * cannot be a blank String (null, empty or whitespace).
+ * @param name cannot be a blank String (null, empty or whitespace).
*/
- public ConstantImpl(final String name) {
+ public AbstractConstantImpl(final String name) {
super(name);
}
- @Override
- public TermType getType() {
- return TermType.CONSTANT;
- }
-
@Override
public T accept(TermVisitor termVisitor) {
return termVisitor.visit(this);
}
-
+
@Override
public String toString() {
- return this.getName();
+ return Serializer.getSerialization(serializer -> serializer.writeAbstractConstant(this));
}
}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/AbstractLiteralImpl.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/AbstractLiteralImpl.java
similarity index 58%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/AbstractLiteralImpl.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/AbstractLiteralImpl.java
index d2860fd7d..4ee1b98e0 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/AbstractLiteralImpl.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/AbstractLiteralImpl.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.model.implementation;
+package org.semanticweb.rulewerk.core.model.implementation;
/*-
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 - 2019 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,17 +22,13 @@
import java.util.Collections;
import java.util.List;
-import java.util.Set;
+
+import java.util.stream.Stream;
import org.apache.commons.lang3.Validate;
-import org.eclipse.jdt.annotation.NonNull;
-import org.semanticweb.vlog4j.core.model.api.Blank;
-import org.semanticweb.vlog4j.core.model.api.Constant;
-import org.semanticweb.vlog4j.core.model.api.Literal;
-import org.semanticweb.vlog4j.core.model.api.Predicate;
-import org.semanticweb.vlog4j.core.model.api.Term;
-import org.semanticweb.vlog4j.core.model.api.TermType;
-import org.semanticweb.vlog4j.core.model.api.Variable;
+import org.semanticweb.rulewerk.core.model.api.Literal;
+import org.semanticweb.rulewerk.core.model.api.Predicate;
+import org.semanticweb.rulewerk.core.model.api.Term;
/**
* Implements {@link Literal} objects. A literal is a formula of the form
@@ -55,7 +51,7 @@ public abstract class AbstractLiteralImpl implements Literal {
* @param terms non-empty list of non-null terms. List size must be the same
* as the predicate arity.
*/
- public AbstractLiteralImpl(@NonNull final Predicate predicate, @NonNull final List terms) {
+ public AbstractLiteralImpl(final Predicate predicate, final List terms) {
Validate.notNull(predicate, "Literal predicates cannot be null.");
Validate.noNullElements(terms,
"Null terms cannot appear in literals. The list contains a null at position [%d].");
@@ -74,7 +70,7 @@ public int hashCode() {
int result = 1;
result = prime * result + (this.isNegated() ? 1231 : 1237);
result = prime * result + this.getPredicate().hashCode();
- result = prime * result + this.getTerms().hashCode();
+ result = prime * result + this.getArguments().hashCode();
return result;
}
@@ -92,27 +88,12 @@ public boolean equals(final Object obj) {
final Literal other = (Literal) obj;
return this.isNegated() == other.isNegated() && this.getPredicate().equals(other.getPredicate())
- && this.getTerms().equals(other.getTerms());
+ && this.getArguments().equals(other.getArguments());
}
@Override
public String toString() {
- final StringBuilder stringBuilder = new StringBuilder("");
- if (this.isNegated()) {
- stringBuilder.append("~");
- }
- stringBuilder.append(this.getPredicate().getName()).append("(");
- boolean first = true;
- for (final Term term : this.getTerms()) {
- if (first) {
- first = false;
- } else {
- stringBuilder.append(", ");
- }
- stringBuilder.append(term);
- }
- stringBuilder.append(")");
- return stringBuilder.toString();
+ return Serializer.getSerialization(serializer -> serializer.writeLiteral(this));
}
@Override
@@ -121,35 +102,13 @@ public Predicate getPredicate() {
}
@Override
- public List getTerms() {
+ public List getArguments() {
return Collections.unmodifiableList(this.terms);
}
@Override
- public Set getVariables() {
- final TermFilter termFilter = new TermFilter(TermType.VARIABLE);
- for (final Term term : this.terms) {
- term.accept(termFilter);
- }
- return termFilter.getVariables();
- }
-
- @Override
- public Set getConstants() {
- final TermFilter termFilter = new TermFilter(TermType.CONSTANT);
- for (final Term term : this.terms) {
- term.accept(termFilter);
- }
- return termFilter.getConstants();
- }
-
- @Override
- public Set getBlanks() {
- final TermFilter termFilter = new TermFilter(TermType.BLANK);
- for (final Term term : this.terms) {
- term.accept(termFilter);
- }
- return termFilter.getBlanks();
+ public Stream getTerms() {
+ return getArguments().stream().distinct();
}
}
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/AbstractPrefixDeclarationRegistry.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/AbstractPrefixDeclarationRegistry.java
new file mode 100644
index 000000000..0d8de1736
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/AbstractPrefixDeclarationRegistry.java
@@ -0,0 +1,155 @@
+package org.semanticweb.rulewerk.core.model.implementation;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.semanticweb.rulewerk.core.exceptions.PrefixDeclarationException;
+import org.semanticweb.rulewerk.core.exceptions.RulewerkRuntimeException;
+import org.semanticweb.rulewerk.core.model.api.PrefixDeclarationRegistry;
+
+/**
+ * Implementation of the common logic for prefix declaration registries.
+ *
+ * @author Maximilian Marx
+ */
+public abstract class AbstractPrefixDeclarationRegistry implements PrefixDeclarationRegistry {
+
+ /**
+ * Pattern for strings that are permissible as local names in abbreviated forms.
+ */
+ static public final String REGEXP_LOCNAME = "^[a-zA-Z]([/a-zA-Z0-9_-])*$";
+
+ /**
+ * Map associating each prefixName with the full prefixIri.
+ */
+ protected Map prefixes = new HashMap<>();
+
+ /**
+ * Iri holding the base namespace.
+ */
+ protected String baseIri = null;
+
+ @Override
+ public void clear() {
+ baseIri = null;
+ prefixes = new HashMap<>();
+ }
+
+ @Override
+ public String getBaseIri() {
+ if (baseIri == null) {
+ baseIri = PrefixDeclarationRegistry.EMPTY_BASE;
+ }
+
+ return baseIri;
+ }
+
+ @Override
+ public String getPrefixIri(String prefixName) throws PrefixDeclarationException {
+ if (!prefixes.containsKey(prefixName)) {
+ throw new PrefixDeclarationException(
+ "Prefix \"" + prefixName + "\" cannot be resolved (not declared yet).");
+ }
+
+ return prefixes.get(prefixName);
+ }
+
+ @Override
+ public void unsetPrefix(String prefixName) {
+ prefixes.remove(prefixName);
+ }
+
+ @Override
+ public String resolvePrefixedName(String prefixedName) throws PrefixDeclarationException {
+ int colon = prefixedName.indexOf(":");
+ String prefix = prefixedName.substring(0, colon + 1);
+ String suffix = prefixedName.substring(colon + 1);
+
+ return getPrefixIri(prefix) + suffix;
+ }
+
+ @Override
+ public String absolutizeIri(String potentiallyRelativeIri) throws PrefixDeclarationException {
+ URI relative;
+
+ try {
+ relative = new URI(potentiallyRelativeIri);
+ } catch (URISyntaxException e) {
+ throw new PrefixDeclarationException("Failed to parse IRI", e);
+ }
+
+ if (relative.isAbsolute()) {
+ return potentiallyRelativeIri;
+ } else {
+ return getBaseIri() + potentiallyRelativeIri;
+ }
+ }
+
+ @Override
+ public String unresolveAbsoluteIri(String iri, boolean addIriBrackets) {
+ String shortestIri;
+ if (addIriBrackets) {
+ if (!iri.contains(":") && iri.matches(REGEXP_LOCNAME)) {
+ shortestIri = iri;
+ if (baseIri != null && !PrefixDeclarationRegistry.EMPTY_BASE.equals(baseIri)) {
+ throw new RulewerkRuntimeException("Relative IRIs cannot be serialized when a base is declared.");
+ }
+ } else {
+ shortestIri = "<" + iri + ">";
+ }
+ } else {
+ shortestIri = iri;
+ }
+
+ String baseIri = getBaseIri();
+
+ if (!PrefixDeclarationRegistry.EMPTY_BASE.equals(baseIri) && iri.length() > baseIri.length()
+ && iri.startsWith(baseIri)) {
+ String shorterIri = iri.substring(baseIri.length());
+ // Only allow very simple names of this form, to avoid confusion, e.g., with
+ // numbers or boolean literals:
+ if (shorterIri.matches(REGEXP_LOCNAME) && !"true".equals(shorterIri) || !"false".equals(shorterIri)) {
+ shortestIri = shorterIri;
+ }
+ }
+
+ for (Map.Entry entry : prefixes.entrySet()) {
+ int localNameLength = iri.length() - entry.getValue().length();
+ if (localNameLength > 0 && shortestIri.length() > localNameLength + entry.getKey().length()
+ && iri.startsWith(entry.getValue())) {
+ shortestIri = entry.getKey() + iri.substring(entry.getValue().length());
+ }
+ }
+
+ return shortestIri;
+ }
+
+ @Override
+ public Iterator> iterator() {
+ return this.prefixes.entrySet().iterator();
+ }
+}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/AbstractTermImpl.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/AbstractTermImpl.java
similarity index 70%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/AbstractTermImpl.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/AbstractTermImpl.java
index 4af20d433..e6c037d43 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/AbstractTermImpl.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/AbstractTermImpl.java
@@ -1,25 +1,20 @@
-package org.semanticweb.vlog4j.core.model.implementation;
+package org.semanticweb.rulewerk.core.model.implementation;
import org.apache.commons.lang3.Validate;
-import org.eclipse.jdt.annotation.NonNull;
-import org.semanticweb.vlog4j.core.model.api.Blank;
-import org.semanticweb.vlog4j.core.model.api.Constant;
-import org.semanticweb.vlog4j.core.model.api.Term;
-import org.semanticweb.vlog4j.core.model.api.TermType;
-import org.semanticweb.vlog4j.core.model.api.Variable;
+import org.semanticweb.rulewerk.core.model.api.Term;
/*
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -29,8 +24,7 @@
*/
/**
- * Abstract class implementing all methods used by all types of terms
- * ({@link Constant}, {@link Blank}, and {@link Variable}).
+ * Abstract class implementing all methods used by all types of terms.
*
* @author david.carral@tu-dresden.de
*/
@@ -38,7 +32,7 @@ public abstract class AbstractTermImpl implements Term {
private final String name;
- public AbstractTermImpl(@NonNull final String name) {
+ public AbstractTermImpl(final String name) {
Validate.notBlank(name, "Terms cannot be named by blank strings");
this.name = new String(name);
}
@@ -48,9 +42,6 @@ public String getName() {
return this.name;
}
- @Override
- public abstract @NonNull TermType getType();
-
@Override
public int hashCode() {
final int prime = 31;
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/ConjunctionImpl.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/ConjunctionImpl.java
new file mode 100644
index 000000000..6da458d75
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/ConjunctionImpl.java
@@ -0,0 +1,93 @@
+package org.semanticweb.rulewerk.core.model.implementation;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+import java.util.stream.Stream;
+
+import org.apache.commons.lang3.Validate;
+import org.semanticweb.rulewerk.core.model.api.Conjunction;
+import org.semanticweb.rulewerk.core.model.api.Literal;
+import org.semanticweb.rulewerk.core.model.api.Term;
+
+/**
+ * Simple implementation of {@link Conjunction}.
+ *
+ * @author Markus Krötzsch
+ */
+public class ConjunctionImpl implements Conjunction {
+
+ final List extends T> literals;
+
+ /**
+ * Constructor.
+ *
+ * @param literals a non-null list of literals, that cannot contain null
+ * elements.
+ */
+ public ConjunctionImpl(List extends T> literals) {
+ Validate.noNullElements(literals);
+ this.literals = literals;
+ }
+
+ @Override
+ public List getLiterals() {
+ return Collections.unmodifiableList(this.literals);
+ }
+
+ @Override
+ public Stream getTerms() {
+ return this.literals.stream().flatMap(l -> l.getTerms()).distinct();
+ }
+
+ @Override
+ public int hashCode() {
+ return this.literals.hashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof Conjunction>)) {
+ return false;
+ }
+ final Conjunction> other = (Conjunction>) obj;
+ return this.literals.equals(other.getLiterals());
+ }
+
+ @Override
+ public Iterator iterator() {
+ return getLiterals().iterator();
+ }
+
+ @Override
+ public String toString() {
+ return Serializer.getSerialization(serializer -> serializer.writeLiteralConjunction(this));
+ }
+
+}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/DataSourceDeclarationImpl.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/DataSourceDeclarationImpl.java
similarity index 79%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/DataSourceDeclarationImpl.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/DataSourceDeclarationImpl.java
index 150475b47..c031d5af4 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/DataSourceDeclarationImpl.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/DataSourceDeclarationImpl.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.model.implementation;
+package org.semanticweb.rulewerk.core.model.implementation;
/*-
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 - 2019 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,10 +21,10 @@
*/
import org.apache.commons.lang3.Validate;
-import org.semanticweb.vlog4j.core.model.api.DataSource;
-import org.semanticweb.vlog4j.core.model.api.DataSourceDeclaration;
-import org.semanticweb.vlog4j.core.model.api.Predicate;
-import org.semanticweb.vlog4j.core.model.api.StatementVisitor;
+import org.semanticweb.rulewerk.core.model.api.DataSource;
+import org.semanticweb.rulewerk.core.model.api.DataSourceDeclaration;
+import org.semanticweb.rulewerk.core.model.api.Predicate;
+import org.semanticweb.rulewerk.core.model.api.StatementVisitor;
/**
* Basic implementation for {@link DataSourceDeclaration}.
@@ -77,7 +77,7 @@ public boolean equals(final Object obj) {
return (this.predicate.equals(other.getPredicate())) && this.dataSource.equals(other.getDataSource());
}
-
+
@Override
public T accept(StatementVisitor statementVisitor) {
return statementVisitor.visit(this);
@@ -85,8 +85,7 @@ public T accept(StatementVisitor statementVisitor) {
@Override
public String toString() {
- return "@source " + this.predicate.toString() + "(" + this.predicate.getArity() + ") : "
- + this.dataSource.toConfigString() + " .";
+ return Serializer.getSerialization(serializer -> serializer.writeDataSourceDeclaration(this));
}
}
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/DatatypeConstantImpl.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/DatatypeConstantImpl.java
new file mode 100644
index 000000000..f4810bee4
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/DatatypeConstantImpl.java
@@ -0,0 +1,101 @@
+package org.semanticweb.rulewerk.core.model.implementation;
+
+import org.apache.commons.lang3.Validate;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import org.semanticweb.rulewerk.core.model.api.DatatypeConstant;
+import org.semanticweb.rulewerk.core.model.api.TermVisitor;
+
+/**
+ * Simple implementation of {@link DatatypeConstant}.
+ *
+ * @author Markus Kroetzsch
+ *
+ */
+public class DatatypeConstantImpl implements DatatypeConstant {
+
+ final String datatype;
+ final String lexicalValue;
+
+ public DatatypeConstantImpl(String lexicalValue, String datatype) {
+ Validate.notNull(lexicalValue);
+ Validate.notBlank(datatype, "Datatype IRIs cannot be blank strings.");
+ this.lexicalValue = lexicalValue;
+ this.datatype = datatype;
+ }
+
+ @Override
+ public T accept(TermVisitor termVisitor) {
+ return termVisitor.visit(this);
+ }
+
+ @Override
+ public String getDatatype() {
+ return this.datatype;
+ }
+
+ @Override
+ public String getLexicalValue() {
+ return this.lexicalValue;
+ }
+
+ @Override
+ public String getRdfLiteralString(boolean useAbbreviations) {
+ if (useAbbreviations) {
+ return Serializer.getSerialization(serializer -> serializer.writeDatatypeConstant(this));
+ } else {
+ return Serializer.getSerialization(serializer -> serializer.writeDatatypeConstantNoAbbreviations(this));
+ }
+ }
+
+ @Override
+ public String toString() {
+ return Serializer.getSerialization(serializer -> serializer.writeDatatypeConstant(this));
+ }
+
+ @Override
+ public String getName() {
+ return toString();
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = datatype.hashCode();
+ result = prime * result + lexicalValue.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ DatatypeConstantImpl other = (DatatypeConstantImpl) obj;
+
+ return this.lexicalValue.equals(other.getLexicalValue()) && this.datatype.equals(other.getDatatype());
+ }
+
+}
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/ExistentialVariableImpl.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/ExistentialVariableImpl.java
new file mode 100644
index 000000000..3a130ee21
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/ExistentialVariableImpl.java
@@ -0,0 +1,51 @@
+package org.semanticweb.rulewerk.core.model.implementation;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import org.semanticweb.rulewerk.core.model.api.TermVisitor;
+import org.semanticweb.rulewerk.core.model.api.ExistentialVariable;
+
+/**
+ * Simple implementation of {@link ExistentialVariable}.
+ *
+ * @author Markus Kroetzsch
+ */
+public class ExistentialVariableImpl extends AbstractTermImpl implements ExistentialVariable {
+
+ /**
+ * Constructor.
+ *
+ * @param name cannot be a blank String (null, empty or whitespace).
+ */
+ public ExistentialVariableImpl(final String name) {
+ super(name);
+ }
+
+ @Override
+ public T accept(TermVisitor termVisitor) {
+ return termVisitor.visit(this);
+ }
+
+ @Override
+ public String toString() {
+ return Serializer.getSerialization(serializer -> serializer.writeExistentialVariable(this));
+ }
+}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/Expressions.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/Expressions.java
similarity index 78%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/Expressions.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/Expressions.java
index 54a87edf9..1d465c4b1 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/Expressions.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/Expressions.java
@@ -1,12 +1,10 @@
-package org.semanticweb.vlog4j.core.model.implementation;
-
-import java.util.ArrayList;
+package org.semanticweb.rulewerk.core.model.implementation;
/*-
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,29 +20,34 @@
* #L%
*/
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import org.eclipse.jdt.annotation.NonNull;
-import org.semanticweb.vlog4j.core.model.api.Conjunction;
-import org.semanticweb.vlog4j.core.model.api.Constant;
-import org.semanticweb.vlog4j.core.model.api.Fact;
-import org.semanticweb.vlog4j.core.model.api.Literal;
-import org.semanticweb.vlog4j.core.model.api.NegativeLiteral;
-import org.semanticweb.vlog4j.core.model.api.PositiveLiteral;
-import org.semanticweb.vlog4j.core.model.api.Predicate;
-import org.semanticweb.vlog4j.core.model.api.Rule;
-import org.semanticweb.vlog4j.core.model.api.Term;
-import org.semanticweb.vlog4j.core.model.api.Variable;
+import org.semanticweb.rulewerk.core.model.api.AbstractConstant;
+import org.semanticweb.rulewerk.core.model.api.Conjunction;
+import org.semanticweb.rulewerk.core.model.api.DatatypeConstant;
+import org.semanticweb.rulewerk.core.model.api.ExistentialVariable;
+import org.semanticweb.rulewerk.core.model.api.Fact;
+import org.semanticweb.rulewerk.core.model.api.LanguageStringConstant;
+import org.semanticweb.rulewerk.core.model.api.Literal;
+import org.semanticweb.rulewerk.core.model.api.NegativeLiteral;
+import org.semanticweb.rulewerk.core.model.api.PositiveLiteral;
+import org.semanticweb.rulewerk.core.model.api.Predicate;
+import org.semanticweb.rulewerk.core.model.api.Rule;
+import org.semanticweb.rulewerk.core.model.api.Term;
+import org.semanticweb.rulewerk.core.model.api.UniversalVariable;
/**
* This utilities class provides static methods for creating terms and formulas
- * in vlog4j.
- *
+ * in Rulewerk.
+ *
* @author Markus Krötzsch
*
*/
+
public final class Expressions {
+
/**
* Private constructor prevents this utilities class to be instantiated.
*/
@@ -52,44 +55,61 @@ private Expressions() {
}
/**
- * Creates a {@link Variable}.
- *
+ * Creates a {@link UniversalVariable}.
+ *
+ * @param name name of the variable
+ * @return a {@link UniversalVariable} corresponding to the input.
+ */
+ public static UniversalVariable makeUniversalVariable(String name) {
+ return new UniversalVariableImpl(name);
+ }
+
+ /**
+ * Creates an {@link ExistentialVariable}.
+ *
* @param name name of the variable
- * @return a {@link Variable} corresponding to the input.
+ * @return a {@link ExistentialVariable} corresponding to the input.
*/
- public static Variable makeVariable(String name) {
- return new VariableImpl(name);
+ public static ExistentialVariable makeExistentialVariable(String name) {
+ return new ExistentialVariableImpl(name);
}
/**
- * Creates a {@link Constant}.
- *
+ * Creates an {@link AbstractConstant}.
+ *
* @param name name of the constant
- * @return a {@link Constant} corresponding to the input.
+ * @return an {@link AbstractConstant} corresponding to the input.
*/
- public static Constant makeConstant(String name) {
- return new ConstantImpl(name);
+ public static AbstractConstant makeAbstractConstant(String name) {
+ return new AbstractConstantImpl(name);
}
/**
- * Creates a {@link Constant} that represents a datatype literal.
- *
- * Note that datatype literal is the common name of the representation of
- * specific values for a datatype. We mostly avoid this meaning of
- * literal since a literal in logic is typically a negated or non-negated
- * atom.
- *
+ * Creates a {@link DatatypeConstant} from the given input.
+ *
* @param lexicalValue the lexical representation of the data value
* @param datatypeIri the full absolute IRI of the datatype of this literal
- * @return a {@link Constant} corresponding to the input.
+ * @return a {@link DatatypeConstant} corresponding to the input.
+ */
+ public static DatatypeConstant makeDatatypeConstant(String lexicalValue, String datatypeIri) {
+ return new DatatypeConstantImpl(lexicalValue, datatypeIri);
+ }
+
+ /**
+ * Creates a {@link LanguageStringConstant} from the given input.
+ *
+ * @param string the string value of the constant
+ * @param languageTag the BCP 47 language tag of the constant; should be in
+ * lower case
+ * @return a {@link LanguageStringConstant} corresponding to the input.
*/
- public static Constant makeDatatypeConstant(String lexicalValue, String datatypeIri) {
- return new ConstantImpl("\"" + lexicalValue + "\"^^<" + datatypeIri + ">");
+ public static LanguageStringConstant makeLanguageStringConstant(String string, String languageTag) {
+ return new LanguageStringConstantImpl(string, languageTag);
}
/**
* Creates a {@link Predicate}.
- *
+ *
* @param name non-blank predicate name
* @param arity predicate arity, strictly greater than 0
* @return a {@link Predicate} corresponding to the input.
@@ -113,12 +133,12 @@ public static Fact makeFact(final String predicateName, final List terms)
return new FactImpl(predicate, terms);
}
-
+
/**
* Creates a {@code Fact}.
- *
+ *
* @param predicateName on-blank {@link Predicate} name
- * @param terms non-empty, non-null array of non-null terms
+ * @param terms non-empty, non-null array of non-null terms
* @return a {@link Fact} with given {@code terms} and {@link Predicate}
* constructed from name given {@code predicateName} and {@code arity}
* given {@code terms} size.
@@ -140,7 +160,7 @@ public static Fact makeFact(final String predicateName, Term... terms) {
public static Fact makeFact(final Predicate predicate, final List terms) {
return new FactImpl(predicate, terms);
}
-
+
/**
* Creates a {@code Fact}.
*
@@ -149,8 +169,8 @@ public static Fact makeFact(final Predicate predicate, final List terms) {
* be the same as the given {@code predicate} arity.
* @return a {@link Fact} corresponding to the input.
*/
- public static Fact makeFact(final Predicate predicate, final Term... terms) {
- return new FactImpl(predicate, Arrays.asList(terms));
+ public static Fact makeFact(final Predicate predicate, final Term... terms) {
+ return new FactImpl(predicate, Arrays.asList(terms));
}
/**
@@ -262,7 +282,7 @@ public static NegativeLiteral makeNegativeLiteral(final Predicate predicate, fin
}
/**
- * Creates a {@code Conjunction} of {@link T} ({@link Literal} type) objects.
+ * Creates a {@link Conjunction} of {@code T} ({@link Literal} type) objects.
*
* @param literals list of non-null literals
* @return a {@link Conjunction} corresponding to the input
@@ -282,7 +302,7 @@ public static Conjunction makeConjunction(final Literal... literals) {
}
/**
- * Creates a {@code Conjunction} of {@link T} ({@link PositiveLiteral} type)
+ * Creates a {@code Conjunction} of {@code T} ({@link PositiveLiteral} type)
* objects.
*
* @param literals list of non-null positive literals
@@ -326,7 +346,7 @@ public static Rule makeRule(final Conjunction head, final Conju
}
/**
- * Creates a {@code Rule}.
+ * Creates a {@link Rule}.
*
* @param head conjunction of positive (non-negated) literals
* @param body conjunction of positive (non-negated) literals
@@ -335,7 +355,6 @@ public static Rule makeRule(final Conjunction head, final Conju
public static Rule makePositiveLiteralsRule(final Conjunction head,
final Conjunction body) {
final List bodyLiteralList = new ArrayList<>(body.getLiterals());
- @NonNull
final Conjunction literalsBody = makeConjunction(bodyLiteralList);
return new RuleImpl(head, literalsBody);
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/FactImpl.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/FactImpl.java
similarity index 54%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/FactImpl.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/FactImpl.java
index a008482d6..aa984d178 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/FactImpl.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/FactImpl.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.model.implementation;
+package org.semanticweb.rulewerk.core.model.implementation;
/*-
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 - 2019 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,31 +22,36 @@
import java.util.List;
-import org.semanticweb.vlog4j.core.model.api.Fact;
-import org.semanticweb.vlog4j.core.model.api.Predicate;
-import org.semanticweb.vlog4j.core.model.api.StatementVisitor;
-import org.semanticweb.vlog4j.core.model.api.Term;
-import org.semanticweb.vlog4j.core.model.api.TermType;
+import org.semanticweb.rulewerk.core.model.api.Fact;
+import org.semanticweb.rulewerk.core.model.api.Predicate;
+import org.semanticweb.rulewerk.core.model.api.StatementVisitor;
+import org.semanticweb.rulewerk.core.model.api.Term;
/**
- * Standard implementation of the {@Fact} interface.
+ * Standard implementation of the {@link Fact} interface.
*
* @author Markus Kroetzsch
*
*/
public class FactImpl extends PositiveLiteralImpl implements Fact {
- public FactImpl(Predicate predicate, List terms) {
+ public FactImpl(final Predicate predicate, final List terms) {
super(predicate, terms);
- for (Term t : terms) {
- if (t.getType() == TermType.VARIABLE)
+ for (final Term t : terms) {
+ if (t.isVariable()) {
throw new IllegalArgumentException("Facts cannot contain variables.");
+ }
}
}
-
+
@Override
- public T accept(StatementVisitor statementVisitor) {
+ public T accept(final StatementVisitor statementVisitor) {
return statementVisitor.visit(this);
}
+ @Override
+ public String toString() {
+ return Serializer.getSerialization(serializer -> serializer.writeFact(this));
+ }
+
}
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/LanguageStringConstantImpl.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/LanguageStringConstantImpl.java
new file mode 100644
index 000000000..e7ab0f8dd
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/LanguageStringConstantImpl.java
@@ -0,0 +1,90 @@
+package org.semanticweb.rulewerk.core.model.implementation;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import org.apache.commons.lang3.Validate;
+import org.semanticweb.rulewerk.core.model.api.LanguageStringConstant;
+import org.semanticweb.rulewerk.core.model.api.TermVisitor;
+
+/**
+ * Simple implementation of {@link LanguageStringConstant}.
+ *
+ * @author Markus Kroetzsch
+ *
+ */
+public class LanguageStringConstantImpl implements LanguageStringConstant {
+
+ final String string;
+ final String lang;
+
+ public LanguageStringConstantImpl(String string, String languageTag) {
+ Validate.notNull(string);
+ Validate.notBlank(languageTag, "Language tags cannot be blank strings.");
+ this.string = string;
+ this.lang = languageTag;
+ }
+
+ @Override
+ public String getName() {
+ return toString();
+ }
+
+ @Override
+ public T accept(TermVisitor termVisitor) {
+ return termVisitor.visit(this);
+ }
+
+ @Override
+ public String getString() {
+ return this.string;
+ }
+
+ @Override
+ public String getLanguageTag() {
+ return this.lang;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = lang.hashCode();
+ result = prime * result + string.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ LanguageStringConstantImpl other = (LanguageStringConstantImpl) obj;
+ return this.string.equals(other.getString()) && this.lang.equals(other.getLanguageTag());
+ }
+
+ @Override
+ public String toString() {
+ return Serializer.getSerialization(serializer -> serializer.writeLanguageStringConstant(this));
+ }
+
+}
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/MergingPrefixDeclarationRegistry.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/MergingPrefixDeclarationRegistry.java
new file mode 100644
index 000000000..3413f19c4
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/MergingPrefixDeclarationRegistry.java
@@ -0,0 +1,129 @@
+package org.semanticweb.rulewerk.core.model.implementation;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import java.util.Map.Entry;
+
+import org.apache.commons.lang3.Validate;
+import org.semanticweb.rulewerk.core.model.api.PrefixDeclarationRegistry;
+
+/**
+ * Implementation of {@link PrefixDeclarationRegistry} that is suitable for
+ * incrementally parsing from multiple sources. When trying to merge in
+ * conflicting prefix declarations, a fresh non-conflicting prefix is generated
+ * instead.
+ *
+ * @author Maximilian Marx
+ */
+final public class MergingPrefixDeclarationRegistry extends AbstractPrefixDeclarationRegistry {
+ /**
+ * Next index to use for generated prefix names.
+ */
+ private Integer nextIndex = 0;
+
+ /**
+ * Template string to use for generated prefix name
+ */
+ private static final String GENERATED_PREFIX_TEMPLATE = "rw_gen%d"
+ + PrefixDeclarationRegistry.PREFIX_NAME_SEPARATOR;
+
+ public MergingPrefixDeclarationRegistry() {
+ super();
+ }
+
+ public MergingPrefixDeclarationRegistry(final PrefixDeclarationRegistry prefixDeclarations) {
+ super();
+ mergePrefixDeclarations(prefixDeclarations);
+ }
+
+ /**
+ * Sets the base namespace to the given value. If a base Iri has already been
+ * set, one of them will be added as a prefix declaration with a fresh
+ * prefixName.
+ *
+ * @param baseIri the new base namespace.
+ */
+ @Override
+ public void setBaseIri(String baseIri) {
+ Validate.notNull(baseIri, "baseIri must not be null");
+ if (baseIri == this.baseIri) {
+ return;
+ }
+
+ if (this.baseIri == null) {
+ this.baseIri = baseIri;
+ } else if (this.baseIri == PrefixDeclarationRegistry.EMPTY_BASE) {
+ // we need to keep the empty base, so that we don't
+ // accidentally relativise absolute Iris to
+ // baseIri. Hence, introduce baseIri as a fresh prefix.
+ prefixes.put(getFreshPrefix(), baseIri);
+ } else {
+ prefixes.put(getFreshPrefix(), this.baseIri);
+ this.baseIri = baseIri;
+ }
+ }
+
+ /**
+ * Registers a prefix declaration. If prefixName is already registered for
+ * another IRI, a freshly generated name will be used instead.
+ *
+ * @param prefixName the name of the prefix.
+ * @param prefixIri the IRI of the prefix.
+ */
+ @Override
+ public void setPrefixIri(String prefixName, String prefixIri) {
+ String name;
+ if (prefixes.containsKey(prefixName) && !prefixIri.equals(prefixes.get(prefixName))) {
+ name = getFreshPrefix();
+ } else {
+ name = prefixName;
+ }
+ prefixes.put(name, prefixIri);
+ }
+
+ /**
+ * Merge another set of prefix declarations.
+ *
+ * @param other the set of prefix declarations to merge. Conflicting prefixes
+ * from {@code other} will be renamed.
+ */
+ public void mergePrefixDeclarations(final PrefixDeclarationRegistry other) {
+ this.setBaseIri(other.getBaseIri());
+
+ for (Entry prefix : other) {
+ this.setPrefixIri(prefix.getKey(), prefix.getValue());
+ }
+ }
+
+ private String getNextFreshPrefixCandidate() {
+ return String.format(GENERATED_PREFIX_TEMPLATE, this.nextIndex++);
+ }
+
+ private String getFreshPrefix() {
+ while (true) {
+ String candidate = getNextFreshPrefixCandidate();
+
+ if (!prefixes.containsKey(candidate)) {
+ return candidate;
+ }
+ }
+ }
+}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/BlankImpl.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/NamedNullImpl.java
similarity index 55%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/BlankImpl.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/NamedNullImpl.java
index e36ecb932..0dae674db 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/BlankImpl.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/NamedNullImpl.java
@@ -1,17 +1,17 @@
-package org.semanticweb.vlog4j.core.model.implementation;
+package org.semanticweb.rulewerk.core.model.implementation;
/*
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -20,42 +20,34 @@
* #L%
*/
-import org.semanticweb.vlog4j.core.model.api.Blank;
-import org.semanticweb.vlog4j.core.model.api.TermType;
-import org.semanticweb.vlog4j.core.model.api.TermVisitor;
+import org.semanticweb.rulewerk.core.model.api.NamedNull;
+import org.semanticweb.rulewerk.core.model.api.TermVisitor;
/**
- * Implements {@link Blank} terms. A blank is an entity used to represent
+ * Implements {@link NamedNull} terms. A null is an entity used to represent
* anonymous domain elements introduced during the reasoning process to satisfy
* existential restrictions.
*
* @author david.carral@tu-dresden.de
*/
-public class BlankImpl extends AbstractTermImpl implements Blank {
+public class NamedNullImpl extends AbstractTermImpl implements NamedNull {
/**
- * Instantiates a {@code BlankImpl} object with the name
- * {@code name}.
+ * Constructor.
*
- * @param name
- * cannot be a blank String (null, empty or whitespace).
+ * @param name String that is not blank (null, empty, or whitespace).
*/
- public BlankImpl(final String name) {
+ public NamedNullImpl(final String name) {
super(name);
}
- @Override
- public TermType getType() {
- return TermType.BLANK;
- }
-
@Override
public T accept(TermVisitor termVisitor) {
return termVisitor.visit(this);
}
-
+
@Override
public String toString() {
- return "_" + this.getName();
+ return Serializer.getSerialization(serializer -> serializer.writeNamedNull(this));
}
}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/NegativeLiteralImpl.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/NegativeLiteralImpl.java
similarity index 63%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/NegativeLiteralImpl.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/NegativeLiteralImpl.java
index ceb0a145c..d4efc8496 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/NegativeLiteralImpl.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/NegativeLiteralImpl.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.model.implementation;
+package org.semanticweb.rulewerk.core.model.implementation;
/*-
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 - 2019 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,14 +22,13 @@
import java.util.List;
-import org.eclipse.jdt.annotation.NonNull;
-import org.semanticweb.vlog4j.core.model.api.NegativeLiteral;
-import org.semanticweb.vlog4j.core.model.api.Predicate;
-import org.semanticweb.vlog4j.core.model.api.Term;
+import org.semanticweb.rulewerk.core.model.api.NegativeLiteral;
+import org.semanticweb.rulewerk.core.model.api.Predicate;
+import org.semanticweb.rulewerk.core.model.api.Term;
public class NegativeLiteralImpl extends AbstractLiteralImpl implements NegativeLiteral {
- public NegativeLiteralImpl(@NonNull Predicate predicate, @NonNull List terms) {
+ public NegativeLiteralImpl(final Predicate predicate, final List terms) {
super(predicate, terms);
}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/PositiveLiteralImpl.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/PositiveLiteralImpl.java
similarity index 63%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/PositiveLiteralImpl.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/PositiveLiteralImpl.java
index 84c2899e5..dc0892e78 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/PositiveLiteralImpl.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/PositiveLiteralImpl.java
@@ -1,10 +1,10 @@
-package org.semanticweb.vlog4j.core.model.implementation;
+package org.semanticweb.rulewerk.core.model.implementation;
/*-
* #%L
- * VLog4j Core Components
+ * Rulewerk Core Components
* %%
- * Copyright (C) 2018 - 2019 VLog4j Developers
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
* %%
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,14 +22,13 @@
import java.util.List;
-import org.eclipse.jdt.annotation.NonNull;
-import org.semanticweb.vlog4j.core.model.api.PositiveLiteral;
-import org.semanticweb.vlog4j.core.model.api.Predicate;
-import org.semanticweb.vlog4j.core.model.api.Term;
+import org.semanticweb.rulewerk.core.model.api.PositiveLiteral;
+import org.semanticweb.rulewerk.core.model.api.Predicate;
+import org.semanticweb.rulewerk.core.model.api.Term;
public class PositiveLiteralImpl extends AbstractLiteralImpl implements PositiveLiteral {
- public PositiveLiteralImpl(@NonNull Predicate predicate, @NonNull List terms) {
+ public PositiveLiteralImpl(final Predicate predicate, final List terms) {
super(predicate, terms);
}
}
diff --git a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/PredicateImpl.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/PredicateImpl.java
similarity index 74%
rename from vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/PredicateImpl.java
rename to rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/PredicateImpl.java
index 3ad38a877..accb87bc4 100644
--- a/vlog4j-core/src/main/java/org/semanticweb/vlog4j/core/model/implementation/PredicateImpl.java
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/PredicateImpl.java
@@ -1,95 +1,92 @@
-package org.semanticweb.vlog4j.core.model.implementation;
-
-/*-
- * #%L
- * VLog4j Core Components
- * %%
- * Copyright (C) 2018 VLog4j Developers
- * %%
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- * #L%
- */
-
-import org.apache.commons.lang3.Validate;
-import org.eclipse.jdt.annotation.NonNull;
-import org.semanticweb.vlog4j.core.model.api.Predicate;
-
-/**
- * Implementation for {@link Predicate}. Supports predicates of arity 1 or
- * higher.
- *
- * @author Irina Dragoste
- *
- */
-public class PredicateImpl implements Predicate {
-
- final private String name;
-
- final private int arity;
-
- /**
- * Constructor for {@link Predicate}s of arity 1 or higher.
- *
- * @param name
- * a non-blank String (not null, nor empty or whitespace).
- * @param arity
- * an int value strictly greater than 0.
- */
- public PredicateImpl(@NonNull String name, int arity) {
- Validate.notBlank(name, "Predicates cannot be named by blank Strings.");
- Validate.isTrue(arity > 0, "Predicate arity must be greater than zero: %d", arity);
-
- this.name = name;
- this.arity = arity;
- }
-
- @Override
- public String getName() {
- return this.name;
- }
-
- @Override
- public int getArity() {
- return this.arity;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = this.arity;
- result = prime * result + this.name.hashCode();
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null) {
- return false;
- }
- if (!(obj instanceof Predicate)) {
- return false;
- }
- final Predicate other = (Predicate) obj;
-
- return this.arity == other.getArity() && this.name.equals(other.getName());
- }
-
- @Override
- public String toString() {
- return "PredicateImpl [name=" + this.name + ", arity=" + this.arity + "]";
- }
-
-}
+package org.semanticweb.rulewerk.core.model.implementation;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import org.apache.commons.lang3.Validate;
+import org.semanticweb.rulewerk.core.model.api.Predicate;
+
+/**
+ * Implementation for {@link Predicate}. Supports predicates of arity 1 or
+ * higher.
+ *
+ * @author Irina Dragoste
+ *
+ */
+public class PredicateImpl implements Predicate {
+
+ final private String name;
+
+ final private int arity;
+
+ /**
+ * Constructor for {@link Predicate}s of arity 1 or higher.
+ *
+ * @param name a non-blank String (not null, nor empty or whitespace).
+ * @param arity an int value strictly greater than 0.
+ */
+ public PredicateImpl(final String name, int arity) {
+ Validate.notBlank(name, "Predicates cannot be named by blank Strings.");
+ Validate.isTrue(arity > 0, "Predicate arity must be greater than zero: %d", arity);
+
+ this.name = name;
+ this.arity = arity;
+ }
+
+ @Override
+ public String getName() {
+ return this.name;
+ }
+
+ @Override
+ public int getArity() {
+ return this.arity;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = this.arity;
+ result = prime * result + this.name.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof Predicate)) {
+ return false;
+ }
+ final Predicate other = (Predicate) obj;
+
+ return this.arity == other.getArity() && this.name.equals(other.getName());
+ }
+
+ @Override
+ public String toString() {
+ return Serializer.getSerialization(serializer -> serializer.writePredicate(this));
+ }
+
+}
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/RenamedNamedNull.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/RenamedNamedNull.java
new file mode 100644
index 000000000..140ac7532
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/RenamedNamedNull.java
@@ -0,0 +1,42 @@
+package org.semanticweb.rulewerk.core.model.implementation;
+
+import java.util.UUID;
+
+/*
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import org.semanticweb.rulewerk.core.model.api.NamedNull;
+import org.semanticweb.rulewerk.core.model.implementation.NamedNullImpl;
+
+/**
+ * A {@link NamedNull} term that has been renamed during parsing.
+ *
+ * @author Maximilian Marx
+ */
+public class RenamedNamedNull extends NamedNullImpl {
+ /**
+ * Construct a new renamed named null, with the given UUID as a name.
+ *
+ * @param name the name of the named null.
+ */
+ public RenamedNamedNull(UUID name) {
+ super(name.toString());
+ }
+}
diff --git a/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/RuleImpl.java b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/RuleImpl.java
new file mode 100644
index 000000000..15f35d27e
--- /dev/null
+++ b/rulewerk-core/src/main/java/org/semanticweb/rulewerk/core/model/implementation/RuleImpl.java
@@ -0,0 +1,131 @@
+package org.semanticweb.rulewerk.core.model.implementation;
+
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/*-
+ * #%L
+ * Rulewerk Core Components
+ * %%
+ * Copyright (C) 2018 - 2020 Rulewerk Developers
+ * %%
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * #L%
+ */
+
+import java.util.stream.Stream;
+
+import org.apache.commons.lang3.Validate;
+import org.semanticweb.rulewerk.core.model.api.Conjunction;
+import org.semanticweb.rulewerk.core.model.api.Literal;
+import org.semanticweb.rulewerk.core.model.api.PositiveLiteral;
+import org.semanticweb.rulewerk.core.model.api.Rule;
+import org.semanticweb.rulewerk.core.model.api.StatementVisitor;
+import org.semanticweb.rulewerk.core.model.api.Term;
+import org.semanticweb.rulewerk.core.model.api.UniversalVariable;
+
+/**
+ * Implementation for {@link Rule}. Represents rules with non-empty heads and
+ * bodies.
+ *
+ * @author Irina Dragoste
+ *
+ */
+public class RuleImpl implements Rule {
+
+ final Conjunction body;
+ final Conjunction head;
+
+ /**
+ * Creates a Rule with a non-empty body and an non-empty head. All variables in
+ * the body must be universally quantified; all variables in the head that do
+ * not occur in the body must be existentially quantified.
+ *
+ * @param head list of Literals (negated or non-negated) representing the rule
+ * body conjuncts.
+ * @param body list of positive (non-negated) Literals representing the rule
+ * head conjuncts.
+ */
+ public RuleImpl(final Conjunction head, final Conjunction body) {
+ Validate.notNull(head);
+ Validate.notNull(body);
+ Validate.notEmpty(body.getLiterals(),
+ "Empty rule body not supported. Use Fact objects to assert unconditionally true atoms.");
+ Validate.notEmpty(head.getLiterals(),
+ "Empty rule head not supported. To capture integrity constraints, use a dedicated predicate that represents a contradiction.");
+ if (body.getExistentialVariables().count() > 0) {
+ throw new IllegalArgumentException(
+ "Rule body cannot contain existential variables. Rule was: " + head + " :- " + body);
+ }
+ Set bodyVariables = body.getUniversalVariables().collect(Collectors.toSet());
+ if (head.getUniversalVariables().filter(x -> !bodyVariables.contains(x)).count() > 0) {
+ throw new IllegalArgumentException(
+ "Universally quantified variables in rule head must also occur in rule body. Rule was: " + head
+ + " :- " + body);
+ }
+
+ this.head = head;
+ this.body = body;
+
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = this.body.hashCode();
+ result = prime * result + this.head.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (!(obj instanceof Rule)) {
+ return false;
+ }
+ final Rule other = (Rule) obj;
+
+ return this.head.equals(other.getHead()) && this.body.equals(other.getBody());
+ }
+
+ @Override
+ public String toString() {
+ return Serializer.getSerialization(serializer -> serializer.writeRule(this));
+ }
+
+ @Override
+ public Conjunction getHead() {
+ return this.head;
+ }
+
+ @Override
+ public Conjunction getBody() {
+ return this.body;
+ }
+
+ @Override
+ public