From 76572615ccddc282216944f838fa2b6099b09e91 Mon Sep 17 00:00:00 2001 From: larsbengel <77848869+larsbengel@users.noreply.github.com> Date: Sun, 14 Jun 2026 22:35:52 +0200 Subject: [PATCH 01/14] some new stuff for serialisation web interface --- .../SerialisationCalleeFactory.java | 4 ++ .../serialisation/SerialisationFactory.java | 39 +++++++++++++++++++ .../SerialisationInfoResponse.java | 4 ++ .../serialisation/SerialisationPost.java | 4 ++ .../serialisation/SerialisationResponse.java | 4 ++ 5 files changed, 55 insertions(+) create mode 100644 org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationCalleeFactory.java create mode 100644 org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationFactory.java create mode 100644 org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationInfoResponse.java create mode 100644 org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationPost.java create mode 100644 org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationResponse.java diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationCalleeFactory.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationCalleeFactory.java new file mode 100644 index 000000000..ce5984633 --- /dev/null +++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationCalleeFactory.java @@ -0,0 +1,4 @@ +package org.tweetyproject.web.services.serialisation; + +public class SerialisationCalleeFactory { +} diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationFactory.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationFactory.java new file mode 100644 index 000000000..d249434af --- /dev/null +++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationFactory.java @@ -0,0 +1,39 @@ +package org.tweetyproject.web.services.serialisation; + +public class SerialisationFactory { + + public enum Command { + GET_REDUCT("get_reduct", "Get Reduct for the given state"), + IS_TERMINAL("is_terminal", "Determine whether the given state is terminal"), + GET_SELECTION("get_selection", "Get the selectable initial sets of the state"); + + /** ID of the command */ + public final String id; + /** Label of the command */ + public final String label; + + /** + * Constructor for Command enum. + * + * @param id ID of the command + * @param label Label of the command + */ + Command(String id, String label) { + this.id = id; + this.label = label; + } + + /** + * Retrieves the Command enum based on the provided ID. + * + * @param id ID of the command + * @return The corresponding Command enum, or null if not found + */ + public static Command getCommand(String id) { + for (Command m : Command.values()) + if (m.id.equals(id)) + return m; + return null; + } + } +} diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationInfoResponse.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationInfoResponse.java new file mode 100644 index 000000000..7174db814 --- /dev/null +++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationInfoResponse.java @@ -0,0 +1,4 @@ +package org.tweetyproject.web.services.serialisation; + +public class SerialisationInfoResponse { +} diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationPost.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationPost.java new file mode 100644 index 000000000..b71be7d8a --- /dev/null +++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationPost.java @@ -0,0 +1,4 @@ +package org.tweetyproject.web.services.serialisation; + +public class SerialisationPost { +} diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationResponse.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationResponse.java new file mode 100644 index 000000000..533f19c4e --- /dev/null +++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationResponse.java @@ -0,0 +1,4 @@ +package org.tweetyproject.web.services.serialisation; + +public class SerialisationResponse { +} From a91813f7bcaf8ec1249b3830d4edff3786967bff Mon Sep 17 00:00:00 2001 From: larsbengel <77848869+larsbengel@users.noreply.github.com> Date: Mon, 15 Jun 2026 00:26:42 +0200 Subject: [PATCH 02/14] added web interface for serialisability --- .../web/services/RequestController.java | 106 +++++ .../SerialisationCalleeFactory.java | 111 +++++ .../serialisation/SerialisationFactory.java | 123 +++-- .../SerialisationGetModelsCallee.java | 49 ++ .../SerialisationGetReductCallee.java | 53 +++ .../SerialisationGetSelectionCallee.java | 64 +++ .../SerialisationGetSequencesCallee.java | 56 +++ .../SerialisationInfoResponse.java | 277 ++++++++++- .../SerialisationIsTerminalCallee.java | 60 +++ .../serialisation/SerialisationPost.java | 215 ++++++++- .../serialisation/SerialisationResponse.java | 446 +++++++++++++++++- .../RequestControllerSerialisationTest.java | 338 +++++++++++++ 12 files changed, 1865 insertions(+), 33 deletions(-) create mode 100644 org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationGetModelsCallee.java create mode 100644 org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationGetReductCallee.java create mode 100644 org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationGetSelectionCallee.java create mode 100644 org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationGetSequencesCallee.java create mode 100644 org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationIsTerminalCallee.java create mode 100644 org-tweetyproject-web/src/test/java/org/tweetyproject/web/services/RequestControllerSerialisationTest.java diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/RequestController.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/RequestController.java index 81a1b77a8..c1a48e8b0 100644 --- a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/RequestController.java +++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/RequestController.java @@ -51,6 +51,9 @@ import org.tweetyproject.arg.bipolar.syntax.BipolarArgumentationFramework; import org.tweetyproject.arg.dung.reasoner.IncompleteReasoner; import org.tweetyproject.arg.dung.semantics.Semantics; +import org.tweetyproject.arg.dung.serialisability.semantics.SerialisationSequence; +import org.tweetyproject.arg.dung.serialisability.syntax.SelectionFunction; +import org.tweetyproject.arg.dung.serialisability.syntax.TerminationFunction; import org.tweetyproject.arg.dung.syntax.Argument; import org.tweetyproject.arg.dung.syntax.Attack; import org.tweetyproject.arg.dung.syntax.DungTheory; @@ -129,6 +132,7 @@ import org.tweetyproject.arg.dung.semantics.Extension; import javafx.util.Pair; +import org.tweetyproject.web.services.serialisation.*; import javax.validation.Valid; import java.util.logging.Level; @@ -1452,4 +1456,106 @@ private PafServicesInfoResponse getPafInfo(String email) { response.setSolvers(AbstractPafReasonerFactory.getSolvers()); return response; } + + /** + * Handles HTTP POST requests for Serialisation operations. + * + *

Supported commands: + *

+ * + * @param serPost the request payload + * @return a {@link Response} containing the computed result or service info + */ + @PostMapping(value = "/serialisation", produces = "application/json", consumes = "application/json") + @ResponseBody + public Response handleRequest(@RequestBody SerialisationPost serPost) { + if (serPost.getCmd().equals("info")) + return getSerInfo(serPost.getEmail()); + + SerialisationCalleeFactory.Command cmd = SerialisationCalleeFactory.Command.getCommand(serPost.getCmd()); + if (cmd == null) + return new SerialisationResponse(); + + DungTheory theory = AbstractExtensionReasonerFactory.getDungTheory( + serPost.getNr_of_arguments(), + serPost.getAttacks()); + Extension extension = SerialisationFactory.getExtension(serPost.getExtension()); + SelectionFunction alpha = SerialisationFactory.getSelectionFunction(serPost.getSelectionFunction()); + TerminationFunction beta = SerialisationFactory.getTerminationFunction(serPost.getTerminationFunction()); + Callee callee = SerialisationCalleeFactory.getCallee(cmd, alpha, beta, theory, extension); + + ExecutorService executor = Executors.newSingleThreadExecutor(); + SerialisationResponse reasonerResponse = new SerialisationResponse( + serPost.getCmd(), serPost.getEmail(), serPost.getNr_of_arguments(), serPost.getAttacks(), + serPost.getExtension(), serPost.getSelectionFunction(), + serPost.getTerminationFunction(), null, 0, + serPost.getUnit_timeout(), "ERROR"); + TimeUnit unit = Utils.getTimeoutUnit(serPost.getUnit_timeout()); + int user_timeout = Utils.checkUserTimeout(serPost.getTimeout(), SERVICES_TIMEOUT_DUNG, unit); + try { + String result_str; + switch (cmd) { + case GET_SEQUENCES -> { + Future> future = executor.submit(callee); + Pair, Long> result = Utils.runServicesWithTimeout(future, user_timeout, unit); + result_str = result.getKey().toString(); + } case GET_REDUCT -> { + Future future = executor.submit(callee); + Pair result = Utils.runServicesWithTimeout(future, user_timeout, unit); + result_str = result.getKey().toString(); + } case IS_TERMINAL -> { + Future future = executor.submit(callee); + Pair result = Utils.runServicesWithTimeout(future, user_timeout, unit); + result_str = result.getKey().toString(); + } case GET_SELECTION,GET_MODELS -> { + Future>> future = executor.submit(callee); + Pair>, Long> result = Utils.runServicesWithTimeout(future, user_timeout, unit); + result_str = result.getKey().toString(); + } default -> throw new IllegalArgumentException("unknown command " + cmd); + + /* + + */ + + } + // TODO update result type; need to make distinction here i guess + Future future = executor.submit(callee); + Pair result = Utils.runServicesWithTimeout(future, user_timeout, unit); + executor.shutdownNow(); + reasonerResponse.setAnswer(result_str); + reasonerResponse.setTime(result.getValue()); + reasonerResponse.setStatus("SUCCESS"); + } catch (TimeoutException e) { + reasonerResponse.setTime(serPost.getTimeout()); + reasonerResponse.setAnswer(null); + reasonerResponse.setStatus("TIMEOUT"); + executor.shutdownNow(); + } catch (Exception e) { + reasonerResponse.setTime(0.0); + reasonerResponse.setAnswer(null); + reasonerResponse.setStatus("Error"); + executor.shutdownNow(); + } + return reasonerResponse; + } + + private SerialisationInfoResponse getSerInfo(String email) { + SerialisationInfoResponse response = new SerialisationInfoResponse(); + response.setReply("info"); + response.setEmail(email); + response.setBackend_timeout(SERVICES_TIMEOUT_DUNG); + response.setSelectionFunctions(SerialisationFactory.getSelectionFunctions()); + response.setTerminationFunctions(SerialisationFactory.getTerminationFunction()); + SerialisationCalleeFactory.Command[] com = SerialisationCalleeFactory.getCommands(); + ArrayList command_ids = new ArrayList<>(); + for (SerialisationCalleeFactory.Command c : com) + command_ids.add(c.id); + response.setCommands(command_ids); + return response; + } } diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationCalleeFactory.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationCalleeFactory.java index ce5984633..2fde191f0 100644 --- a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationCalleeFactory.java +++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationCalleeFactory.java @@ -1,4 +1,115 @@ +/* + * This file is part of "TweetyProject", a collection of Java libraries for + * logical aspects of artificial intelligence and knowledge representation. + * + * TweetyProject is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Copyright 2026 The TweetyProject Team + */ package org.tweetyproject.web.services.serialisation; +import org.tweetyproject.arg.dung.semantics.Extension; +import org.tweetyproject.arg.dung.serialisability.syntax.SelectionFunction; +import org.tweetyproject.arg.dung.serialisability.syntax.TerminationFunction; +import org.tweetyproject.arg.dung.syntax.DungTheory; +import org.tweetyproject.web.services.Callee; + +/** + * The SerialisationCalleeFactory class is responsible for creating instances of Callee + * based on the specified Command, DungTheory, Extension, Selection and termination function parameters. + * It also defines an enumeration of commands with associated IDs and labels. + */ public class SerialisationCalleeFactory { + /** + * Enumeration of commands supported by the factory, each with a unique ID and label. + */ + public enum Command { + + /** get reduct */ + GET_REDUCT("get_reduct", "Get Reduct for the given state"), + /** is the state terminal */ + IS_TERMINAL("is_terminal", "Determine whether the given state is terminal"), + /** get selection of initial sets */ + GET_SELECTION("get_selection", "Get the selectable initial sets of the state"), + /** get models */ + GET_MODELS("get_models", "Get the extensions for the given functions"), + /** get sequences */ + GET_SEQUENCES("get_sequences", "Get all serialisation sequences for the given functions"); + + /** ID of the command */ + public final String id; + /** Label of the command */ + public final String label; + + /** + * Constructor for Command enum. + * + * @param id ID of the command + * @param label Label of the command + */ + Command(String id, String label) { + this.id = id; + this.label = label; + } + + /** + * Retrieves the Command enum based on the provided ID. + * + * @param id ID of the command + * @return The corresponding Command enum, or null if not found + */ + public static Command getCommand(String id) { + for (Command m : Command.values()) + if (m.id.equals(id)) + return m; + return null; + } + } + + /** + * Retrieves an array of all available Command enums. + * + * @return An array of Command enums + */ + public static Command[] getCommands() { + return Command.values(); + } + + /** + * Creates and returns a Callee instance based on the provided Command, AbstractExtensionReasoner, + * and DungTheory parameters. + * + * @param cmd The command to be executed + * @param alpha The selection function + * @param beta The termination function + * @param bbase The DungTheory to be processed + * @param extension The extension to be processed + * @return A Callee instance corresponding to the specified command + * @throws RuntimeException If the specified command is not found + */ + public static Callee getCallee(Command cmd, SelectionFunction alpha, TerminationFunction beta, DungTheory bbase, Extension extension) { + switch (cmd) { + case GET_REDUCT -> { + return new SerialisationGetReductCallee(bbase, extension); + } case IS_TERMINAL -> { + return new SerialisationIsTerminalCallee(bbase, extension, beta); + } case GET_SELECTION -> { + return new SerialisationGetSelectionCallee(bbase, alpha); + } case GET_MODELS -> { + return new SerialisationGetModelsCallee(bbase, alpha, beta); + } case GET_SEQUENCES -> { + return new SerialisationGetSequencesCallee(bbase, alpha, beta); + } default -> throw new RuntimeException("Command not found: " + cmd); + } + } } diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationFactory.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationFactory.java index d249434af..a0a7d4720 100644 --- a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationFactory.java +++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationFactory.java @@ -1,39 +1,104 @@ +/* + * This file is part of "TweetyProject", a collection of Java libraries for + * logical aspects of artificial intelligence and knowledge representation. + * + * TweetyProject is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Copyright 2026 The TweetyProject Team + */ package org.tweetyproject.web.services.serialisation; -public class SerialisationFactory { +import org.tweetyproject.arg.dung.semantics.Extension; +import org.tweetyproject.arg.dung.serialisability.syntax.SelectionFunction; +import org.tweetyproject.arg.dung.serialisability.syntax.TerminationFunction; +import org.tweetyproject.arg.dung.syntax.Argument; +import org.tweetyproject.arg.dung.syntax.DungTheory; - public enum Command { - GET_REDUCT("get_reduct", "Get Reduct for the given state"), - IS_TERMINAL("is_terminal", "Determine whether the given state is terminal"), - GET_SELECTION("get_selection", "Get the selectable initial sets of the state"); +import java.util.List; - /** ID of the command */ - public final String id; - /** Label of the command */ - public final String label; +/** + * Main factory for retrieving serialisation related things + * + * @author Lars Bengel + */ +public class SerialisationFactory { + /** + * parses an extension from a list of integers + * @param extension extension as a list on integers + * @return the parsed extension + */ + public static Extension getExtension(List extension) { + if (extension==null) return null; + Extension result = new Extension<>(); + for (Integer i : extension) { + result.add(new Argument(Integer.toString(i))); + } + return result; + } - /** - * Constructor for Command enum. - * - * @param id ID of the command - * @param label Label of the command - */ - Command(String id, String label) { - this.id = id; - this.label = label; + /** + * determine the selection function + * @param selectionFunction string id of selection functions + * @return the selection function + */ + public static SelectionFunction getSelectionFunction(String selectionFunction) { + if (selectionFunction==null) return null; + switch (selectionFunction) { + case "ADM" -> { + return SelectionFunction.ADMISSIBLE; + } case "UC" -> { + return SelectionFunction.UNCHALLENGED; + } case "GR" -> { + return SelectionFunction.GROUNDED; + } default -> throw new IllegalArgumentException("unknown selection function " + selectionFunction); } + } - /** - * Retrieves the Command enum based on the provided ID. - * - * @param id ID of the command - * @return The corresponding Command enum, or null if not found - */ - public static Command getCommand(String id) { - for (Command m : Command.values()) - if (m.id.equals(id)) - return m; - return null; + /** + * get all available selection functions + * @return the selection functions + */ + public static List getSelectionFunctions() { + return List.of("ADM", "UC", "GR"); + } + + /** + * determine the termination function + * @param terminationFunction string idf of termination function + * @return the termination function + */ + public static TerminationFunction getTerminationFunction(String terminationFunction) { + if (terminationFunction==null) return null; + switch (terminationFunction) { + case "ADM" -> { + return TerminationFunction.ADMISSIBLE; + } case "UC" -> { + return TerminationFunction.UNCHALLENGED; + } case "CO" -> { + return TerminationFunction.COMPLETE; + } case "PR" -> { + return TerminationFunction.PREFERRED; + } case "ST" -> { + return TerminationFunction.STABLE; + } default -> throw new IllegalArgumentException("unknown selection function " + terminationFunction); } } + + /** + * get all available termination functions + * @return the termination functions + */ + public static List getTerminationFunction() { + return List.of("ADM", "CO", "UC", "PR", "ST"); + } } diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationGetModelsCallee.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationGetModelsCallee.java new file mode 100644 index 000000000..5505fb4c6 --- /dev/null +++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationGetModelsCallee.java @@ -0,0 +1,49 @@ +package org.tweetyproject.web.services.serialisation; + +import org.tweetyproject.arg.dung.reasoner.SerialisedExtensionReasoner; +import org.tweetyproject.arg.dung.semantics.Extension; +import org.tweetyproject.arg.dung.serialisability.syntax.SelectionFunction; +import org.tweetyproject.arg.dung.serialisability.syntax.TerminationFunction; +import org.tweetyproject.arg.dung.syntax.DungTheory; +import org.tweetyproject.web.services.Callee; + +import java.util.Collection; + +/** + * Callee for the getModels operation of the SerialisedExtensionReasoner for the given selection and termination functions + */ +public class SerialisationGetModelsCallee extends Callee { + /** The DungTheory on which the evaluation is performed */ + private final DungTheory bbase; + + /** The selection function to use */ + private final SelectionFunction selectionFunction; + + /** The termination function to use */ + private final TerminationFunction terminationFunction; + + /** + * Constructs a new SerialisationGetModelsCallee with the specified DungTheory and functions. + * + * @param bbase The base DungTheory on which the serialisation is performed + * @param alpha The selection function to be used + * @param beta The termination function to be used + */ + public SerialisationGetModelsCallee(DungTheory bbase, SelectionFunction alpha, TerminationFunction beta) { + this.bbase = bbase; + this.selectionFunction = alpha; + this.terminationFunction = beta; + } + + /** + * Executes the getModels operation using the specified DungTheory the fitting serialised reasoner. + * + * @return the set of models + * @throws Exception If an error occurs during the getModels operation + */ + @Override + public Collection> call() throws Exception { + SerialisedExtensionReasoner reasoner = new SerialisedExtensionReasoner(this.selectionFunction, this.terminationFunction); + return reasoner.getModels(this.bbase); + } +} diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationGetReductCallee.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationGetReductCallee.java new file mode 100644 index 000000000..aff4f6357 --- /dev/null +++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationGetReductCallee.java @@ -0,0 +1,53 @@ +/* + * This file is part of "TweetyProject", a collection of Java libraries for + * logical aspects of artificial intelligence and knowledge representation. + * + * TweetyProject is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Copyright 2026 The TweetyProject Team + */ +package org.tweetyproject.web.services.serialisation; + +import org.tweetyproject.arg.dung.semantics.Extension; +import org.tweetyproject.arg.dung.syntax.DungTheory; +import org.tweetyproject.web.services.Callee; + +public class SerialisationGetReductCallee extends Callee { + /** The Extension used for obtaining the reduct */ + private final Extension extension; + + /** The DungTheory on which the getReduct operation is performed */ + private final DungTheory bbase; + + /** + * Constructs a new SerialisationGetReductCallee with the specified DungTheory and Extension. + * + * @param bbase The base DungTheory on which the getReduct operation is performed + * @param extension The extension by which the getReduct operation is performed + */ + public SerialisationGetReductCallee(DungTheory bbase, Extension extension) { + this.extension = extension; + this.bbase = bbase; + } + + /** + * Executes the getReduct operation using the specified extension and base DungTheory. + * + * @return The Reduct + * @throws Exception If an error occurs during the getReduct operation + */ + @Override + public DungTheory call() throws Exception { + return this.bbase.getReduct(this.extension); + } +} diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationGetSelectionCallee.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationGetSelectionCallee.java new file mode 100644 index 000000000..7f2ce26b9 --- /dev/null +++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationGetSelectionCallee.java @@ -0,0 +1,64 @@ +/* + * This file is part of "TweetyProject", a collection of Java libraries for + * logical aspects of artificial intelligence and knowledge representation. + * + * TweetyProject is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Copyright 2026 The TweetyProject Team + */ +package org.tweetyproject.web.services.serialisation; + +import org.tweetyproject.arg.dung.reasoner.SimpleInitialReasoner; +import org.tweetyproject.arg.dung.semantics.Extension; +import org.tweetyproject.arg.dung.serialisability.syntax.SelectionFunction; +import org.tweetyproject.arg.dung.syntax.DungTheory; +import org.tweetyproject.web.services.Callee; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; + +import static org.tweetyproject.arg.dung.reasoner.SimpleInitialReasoner.Initial.*; + +public class SerialisationGetSelectionCallee extends Callee { + /** The DungTheory on which the selection function is performed */ + private final DungTheory bbase; + + /** The selection function to use */ + private final SelectionFunction selectionFunction; + + /** + * Constructs a new SerialisationGetSelectionCallee with the specified DungTheory and Selection function. + * + * @param bbase The base DungTheory on which the termination status is checked + * @param alpha The selection function to be used + */ + public SerialisationGetSelectionCallee(DungTheory bbase, SelectionFunction alpha) { + this.bbase = bbase; + this.selectionFunction = alpha; + } + + /** + * Executes the getSelection operation using the specified DungTheory and selection function. + * + * @return the set of selectable initial sets + * @throws Exception If an error occurs during the getSelection operation + */ + @Override + public Collection> call() throws Exception { + Map>> initialSets = SimpleInitialReasoner + .partitionInitialSets(this.bbase); + return this.selectionFunction.execute(new HashSet<>(initialSets.get(UA)), new HashSet<>(initialSets.get(UC)), + new HashSet<>(initialSets.get(C))); + } +} diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationGetSequencesCallee.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationGetSequencesCallee.java new file mode 100644 index 000000000..09a989181 --- /dev/null +++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationGetSequencesCallee.java @@ -0,0 +1,56 @@ +package org.tweetyproject.web.services.serialisation; + +import org.tweetyproject.arg.dung.reasoner.SerialisedExtensionReasoner; +import org.tweetyproject.arg.dung.semantics.Extension; +import org.tweetyproject.arg.dung.serialisability.semantics.SerialisationSequence; +import org.tweetyproject.arg.dung.serialisability.syntax.SelectionFunction; +import org.tweetyproject.arg.dung.serialisability.syntax.TerminationFunction; +import org.tweetyproject.arg.dung.syntax.DungTheory; +import org.tweetyproject.web.services.Callee; + +import java.util.Collection; + +/** + * Callee for the getSequences operation of the SerialisedExtensionReasoner for the given selection and termination functions + */ +public class SerialisationGetSequencesCallee extends Callee { + /** + * The DungTheory on which the evaluation is performed + */ + private final DungTheory bbase; + + /** + * The selection function to use + */ + private final SelectionFunction selectionFunction; + + /** + * The termination function to use + */ + private final TerminationFunction terminationFunction; + + /** + * Constructs a new SerialisationGetSequencesCallee with the specified DungTheory and functions. + * + * @param bbase The base DungTheory on which the serialisation is performed + * @param alpha The selection function to be used + * @param beta The termination function to be used + */ + public SerialisationGetSequencesCallee(DungTheory bbase, SelectionFunction alpha, TerminationFunction beta) { + this.bbase = bbase; + this.selectionFunction = alpha; + this.terminationFunction = beta; + } + + /** + * Executes the getSequences operation using the specified DungTheory the fitting serialised reasoner. + * + * @return the set of sequences + * @throws Exception If an error occurs during the getSequences operation + */ + @Override + public Collection call() throws Exception { + SerialisedExtensionReasoner reasoner = new SerialisedExtensionReasoner(this.selectionFunction, this.terminationFunction); + return reasoner.getSequences(this.bbase); + } +} \ No newline at end of file diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationInfoResponse.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationInfoResponse.java index 7174db814..46a8ea542 100644 --- a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationInfoResponse.java +++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationInfoResponse.java @@ -1,4 +1,279 @@ +/* + * This file is part of "TweetyProject", a collection of Java libraries for + * logical aspects of artificial intelligence and knowledge representation. + * + * TweetyProject is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Copyright 2026 The TweetyProject Team + */ package org.tweetyproject.web.services.serialisation; -public class SerialisationInfoResponse { +import java.util.List; +import java.util.Objects; + +import org.tweetyproject.web.services.Response; + + +/** + * The SerialisationInfoResponse class extends the Response class and represents + * a response containing information about Dung argumentation services. + */ +public class SerialisationInfoResponse extends Response { + + /** The reply message in the Serialisation info response */ + private String reply; + + /** The email associated with the Serialisation info response */ + private String email; + + /** The backend timeout value specified in the Serialisation info response */ + private int backend_timeout; + + /** The list of supported selection functions in the Serialisation info response */ + private List selectionFunctions; + + /** The list of supported termination functions in the Serialisation info response */ + private List terminationFunctions; + + /** The list of supported commands in the Serialisation info response */ + private List commands; + + /** + * Default constructor for SerialisationInfoResponse. + */ + public SerialisationInfoResponse() { + } + + /** + * Parameterized constructor for SerialisationInfoResponse. + * + * @param reply The reply message + * @param email The email associated with the response + * @param backend_timeout The backend timeout value + * @param selectionFunctions The list of supported selection functions + * @param terminationFunctions The list of supported termination functions + * @param commands The list of supported commands + */ + public SerialisationInfoResponse(String reply, String email, int backend_timeout, List selectionFunctions, List terminationFunctions, List commands) { + this.reply = reply; + this.email = email; + this.backend_timeout = backend_timeout; + this.selectionFunctions = selectionFunctions; + this.terminationFunctions = terminationFunctions; + this.commands = commands; + } + + /** + * Gets the reply message associated with this response. + * + * @return The current reply message as a string. + */ + public String getReply() { + return this.reply; + } + + /** + * Sets the reply message for this response. + * + * @param reply The reply message to set. + */ + public void setReply(String reply) { + this.reply = reply; + } + + /** + * Gets the email address associated with this response. + * + * @return The email address as a string. + */ + public String getEmail() { + return this.email; + } + + /** + * Sets the email address for this response. + * + * @param email The email address to set. + */ + public void setEmail(String email) { + this.email = email; + } + + /** + * Gets the backend timeout setting for the service. + * + * @return The backend timeout in integer form. + */ + public int getBackend_timeout() { + return this.backend_timeout; + } + + /** + * Sets the backend timeout for the service. + * + * @param backend_timeout The backend timeout value in seconds. + */ + public void setBackend_timeout(int backend_timeout) { + this.backend_timeout = backend_timeout; + } + + /** + * Gets the list of selection functions associated with the service. + * + * @return A list of selection functions as strings. + */ + public List getSelectionFunctions() { + return this.selectionFunctions; + } + + /** + * Gets the list of termination functions associated with the service. + * + * @return A list of termination functions as strings. + */ + public List getTerminationFunctions() { + return this.terminationFunctions; + } + + /** + * Gets the list of commands associated with the service. + * + * @return A list of commands as strings. + */ + public List getCommands() { + return this.commands; + } + + /** + * Sets the list of commands for the service. + * + * @param commands A list of command strings to be utilized by the service. + */ + public void setCommands(List commands) { + this.commands = commands; + } + + /** + * Sets the list of selectionFunctions for the service. + * + * @param selectionFunctions A list of command strings to be utilized by the service. + */ + public void setSelectionFunctions(List selectionFunctions) { + this.selectionFunctions = selectionFunctions; + } + + /** + * Sets the list of terminationFunctions for the service. + * + * @param terminationFunctions A list of command strings to be utilized by the service. + */ + public void setTerminationFunctions(List terminationFunctions) { + this.terminationFunctions = terminationFunctions; + } + + // Fluent setters + + /** + * Sets the reply message and returns this instance for method chaining. + * + * @param reply The reply message to set. + * @return This instance to facilitate further modifications. + */ + public SerialisationInfoResponse reply(String reply) { + setReply(reply); + return this; + } + + /** + * Sets the email address and returns this instance for method chaining. + * + * @param email The email address to set. + * @return This instance to facilitate further modifications. + */ + public SerialisationInfoResponse email(String email) { + setEmail(email); + return this; + } + + /** + * Sets the backend timeout and returns this instance for method chaining. + * + * @param backend_timeout The backend timeout in seconds to set. + * @return This instance to facilitate further modifications. + */ + public SerialisationInfoResponse backend_timeout(int backend_timeout) { + setBackend_timeout(backend_timeout); + return this; + } + + /** + * Sets the selectionFunctions and returns this instance for method chaining. + * + * @param selectionFunctions A list of selectionFunctions strings to set. + * @return This instance to facilitate further modifications. + */ + public SerialisationInfoResponse selectionFunctions(List selectionFunctions) { + setSelectionFunctions(selectionFunctions); + return this; + } + + /** + * Sets the terminationFunctions and returns this instance for method chaining. + * + * @param terminationFunctions A list of terminationFunctions strings to set. + * @return This instance to facilitate further modifications. + */ + public SerialisationInfoResponse terminationFunctions(List terminationFunctions) { + setTerminationFunctions(terminationFunctions); + return this; + } + + /** + * Sets the commands and returns this instance for method chaining. + * + * @param commands A list of command strings to set. + * @return This instance to facilitate further modifications. + */ + public SerialisationInfoResponse commands(List commands) { + setCommands(commands); + return this; + } + + @Override + public boolean equals(Object o) { + if (o == this) + return true; + if (!(o instanceof SerialisationInfoResponse)) { + return false; + } + SerialisationInfoResponse infoResponse = (SerialisationInfoResponse) o; + return Objects.equals(reply, infoResponse.reply) && Objects.equals(email, infoResponse.email) && backend_timeout == infoResponse.backend_timeout && Objects.equals(selectionFunctions, infoResponse.selectionFunctions) && Objects.equals(terminationFunctions, infoResponse.terminationFunctions) && Objects.equals(commands, infoResponse.commands); + } + + @Override + public int hashCode() { + return Objects.hash(reply, email, backend_timeout, selectionFunctions, terminationFunctions, commands); + } + + @Override + public String toString() { + return "{" + + " reply='" + getReply() + "'" + + ", email='" + getEmail() + "'" + + ", backend_timeout='" + getBackend_timeout() + "'" + + ", selectionFunctions='" + getSelectionFunctions() + "'" + + ", terminationFunctions='" + getTerminationFunctions() + "'" + + ", commands='" + getCommands() + "'" + + "}"; + } } diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationIsTerminalCallee.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationIsTerminalCallee.java new file mode 100644 index 000000000..b34d24bae --- /dev/null +++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationIsTerminalCallee.java @@ -0,0 +1,60 @@ +/* + * This file is part of "TweetyProject", a collection of Java libraries for + * logical aspects of artificial intelligence and knowledge representation. + * + * TweetyProject is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Copyright 2026 The TweetyProject Team + */ +package org.tweetyproject.web.services.serialisation; + +import org.tweetyproject.arg.dung.semantics.Extension; +import org.tweetyproject.arg.dung.serialisability.syntax.TerminationFunction; +import org.tweetyproject.arg.dung.syntax.DungTheory; +import org.tweetyproject.web.services.Callee; + +public class SerialisationIsTerminalCallee extends Callee { + + /** The Extension used for obtaining the termination status */ + private final Extension extension; + + /** The DungTheory on which the termination function is performed */ + private final DungTheory bbase; + + /** The termination function to use */ + private final TerminationFunction terminationFunction; + + /** + * Constructs a new SerialisationIsTerminalCallee with the specified DungTheory, Extension and Termination function. + * + * @param bbase The base DungTheory on which the termination status is checked + * @param extension The extension by which the termination function is tested + * @param beta The termination function to be used + */ + public SerialisationIsTerminalCallee(DungTheory bbase, Extension extension, TerminationFunction beta) { + this.bbase = bbase; + this.extension = extension; + this.terminationFunction = beta; + } + + /** + * Executes the isTerminal operation using the specified extension and DungTheory by the termination function. + * + * @return "true" if the given state is terminal + * @throws Exception If an error occurs during the isTerminal operation + */ + @Override + public Boolean call() throws Exception { + return this.terminationFunction.execute(this.bbase, this.extension); + } +} diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationPost.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationPost.java index b71be7d8a..d622b1591 100644 --- a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationPost.java +++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationPost.java @@ -1,4 +1,217 @@ +/* + * This file is part of "TweetyProject", a collection of Java libraries for + * logical aspects of artificial intelligence and knowledge representation. + * + * TweetyProject is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Copyright 2026 The TweetyProject Team + */ package org.tweetyproject.web.services.serialisation; +import java.util.List; + +/** + * The SerialisationPost class represents a data structure for holding information + * related to a serialisation request sent via HTTP POST. + */ public class SerialisationPost { -} + + /** The command type for the serialisation request */ + private String cmd; + + /** The email associated with the serialisation request */ + private String email; + + /** The number of arguments in the serialisation request */ + private int nr_of_arguments; + + /** The attacks information in the serialisation request */ + private List> attacks; + + /** The extension in the serialisation request */ + private List extension; + + /** The selection function specified in the serialisation request */ + private String selectionFunction; + + /** The termination function specified in the serialisation request */ + private String terminationFunction; + + /** The timeout value (in seconds) specified in the serialisation request */ + private int timeout; + + /** The unit timeout value specified in the serialisation request */ + private String unit_timeout; + + /** + * Gets the unit timeout value specified in the serialisation request. + * + * @return The unit timeout value + */ + public String getUnit_timeout() { + return unit_timeout; + } + + /** + * Sets the unit timeout value in the serialisation request. + * + * @param unit_timeout The unit timeout value to be set + */ + public void setUnit_timeout(String unit_timeout) { + this.unit_timeout = unit_timeout; + } + + /** + * Gets the command type in the serialisation request. + * + * @return The command type + */ + public String getCmd() { + return this.cmd; + } + + /** + * Sets the command type in the serialisation request. + * + * @param cmd The command type to be set + */ + public void setCmd(String cmd) { + this.cmd = cmd; + } + + /** + * Gets the email associated with the serialisation request. + * + * @return The email associated with the request + */ + public String getEmail() { + return this.email; + } + + /** + * Sets the email associated with the serialisation request. + * + * @param email The email to be set + */ + public void setEmail(String email) { + this.email = email; + } + + /** + * Gets the number of arguments in the serialisation request. + * + * @return The number of arguments + */ + public int getNr_of_arguments() { + return this.nr_of_arguments; + } + + /** + * Sets the number of arguments in the serialisation request. + * + * @param nr_of_arguments The number of arguments to be set + */ + public void setNr_of_arguments(int nr_of_arguments) { + this.nr_of_arguments = nr_of_arguments; + } + + /** + * Gets the attacks information in the serialisation request. + * + * @return The attacks information + */ + public List> getAttacks() { + return this.attacks; + } + + /** + * Sets the attacks information in the serialisation request. + * + * @param attacks The attacks information to be set + */ + public void setAttacks(List> attacks) { + this.attacks = attacks; + } + + /** + * Gets the extension in the serialisation request. + * + * @return The extension + */ + public List getExtension() { + return this.extension; + } + + /** + * Sets the extension in the serialisation request. + * + * @param extension The extension to be set + */ + public void setExtension(List extension) { + this.extension = extension; + } + + /** + * Gets the selection function specified in the serialisation request. + * + * @return The selection function specified + */ + public String getSelectionFunction() { + return this.selectionFunction; + } + + /** + * Sets the selection function in the serialisation request. + * + * @param selectionFunction The selection function to be set + */ + public void setSelectionFunction(String selectionFunction) { + this.selectionFunction = selectionFunction; + } + + /** + * Gets the termination function specified in the serialisation request. + * + * @return The termination function specified + */ + public String getTerminationFunction() { + return this.terminationFunction; + } + + /** + * Sets the termination function in the serialisation request. + * + * @param terminationFunction The termination function to be set + */ + public void setTerminationFunction(String terminationFunction) { + this.terminationFunction = terminationFunction; + } + + /** + * Gets the timeout value (in seconds) specified in the serialisation request. + * + * @return The timeout value + */ + public int getTimeout() { + return this.timeout; + } + + /** + * Sets the timeout value (in seconds) in the serialisation request. + * + * @param timeout The timeout value to be set + */ + public void setTimeout(int timeout) { + this.timeout = timeout; + } +} \ No newline at end of file diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationResponse.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationResponse.java index 533f19c4e..6784913c3 100644 --- a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationResponse.java +++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/serialisation/SerialisationResponse.java @@ -1,4 +1,446 @@ +/* + * This file is part of "TweetyProject", a collection of Java libraries for + * logical aspects of artificial intelligence and knowledge representation. + * + * TweetyProject is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Copyright 2026 The TweetyProject Team + */ package org.tweetyproject.web.services.serialisation; -public class SerialisationResponse { -} +import java.util.List; +import java.util.Objects; + +import org.tweetyproject.web.services.Response; + +/** + * The SerialisationResponse class extends the Response class and represents + * a response containing information related to a serialisation + * result. + */ +public class SerialisationResponse extends Response { + + /** The reply message in the serialisation response */ + private String reply; + + /** The email associated with the serialisation response */ + private String email; + + /** The number of arguments in the serialisation response */ + private int nr_of_arguments; + + /** The attacks information in the serialisation response */ + private List> attacks; + + /** The extension in the serialisation response */ + private List extension; + + /** The selection function specified in the serialisation response */ + private String selectionFunction; + + /** The termination function specified in the serialisation response */ + private String terminationFunction; + + /** The answer provided by the serialisation response */ + private String answer; + + /** The time taken for the serialisation operation (in seconds) */ + private double time; + + /** The unit time specified in the serialisation response */ + private String unit_time; + + /** The status of the serialisation response */ + private String status; + + /** + * Default constructor for SerialisationResponse. + */ + public SerialisationResponse() { + } + + /** + * Parameterized constructor for SerialisationResponse. + * + * @param reply The reply message + * @param email The email associated with the response + * @param nr_of_arguments The number of arguments + * @param attacks The attacks information + * @param extension The extension + * @param selectionFunction The semantics specified + * @param terminationFunction The solver specified + * @param answer The answer provided + * @param time The time taken for the operation + * @param unit_time The unit time specified + * @param status The status of the response + */ + public SerialisationResponse(String reply, String email, int nr_of_arguments, List> attacks, List extension, + String selectionFunction, String terminationFunction, String answer, double time, String unit_time, String status) { + this.reply = reply; + this.email = email; + this.nr_of_arguments = nr_of_arguments; + this.attacks = attacks; + this.extension = extension; + this.selectionFunction = selectionFunction; + this.terminationFunction = terminationFunction; + this.answer = answer; + this.time = time; + this.unit_time = unit_time; + this.status = status; + } + + /** + * Gets the reply message in the serialisation response. + * + * @return The reply message in the serialisation response. + */ + public String getReply() { + return reply; + } + + /** + * Sets the reply message in the serialisation response. + * + * @param reply The reply message in the serialisation response. + */ + public void setReply(String reply) { + this.reply = reply; + } + + /** + * Gets the email associated with the serialisation response. + * + * @return The email associated with the serialisation response. + */ + public String getEmail() { + return email; + } + + /** + * Sets the email associated with the serialisation response. + * + * @param email The email associated with the serialisation response. + */ + public void setEmail(String email) { + this.email = email; + } + + /** + * Gets the number of arguments in the serialisation response. + * + * @return The number of arguments in the serialisation response. + */ + public int getNr_of_arguments() { + return nr_of_arguments; + } + + /** + * Sets the number of arguments in the serialisation response. + * + * @param nr_of_arguments The number of arguments in the serialisation response. + */ + public void setNr_of_arguments(int nr_of_arguments) { + this.nr_of_arguments = nr_of_arguments; + } + + /** + * Gets the attacks information in the serialisation response. + * + * @return The attacks information in the serialisation response. + */ + public List> getAttacks() { + return attacks; + } + + /** + * Sets the attacks information in the serialisation response. + * + * @param attacks The attacks information in the serialisation response. + */ + public void setAttacks(List> attacks) { + this.attacks = attacks; + } + + /** + * Gets the extension in the serialisation response. + * + * @return The extension in the serialisation response. + */ + public List getExtension() { + return extension; + } + + /** + * Sets the extension in the serialisation response. + * + * @param extension The extension in the serialisation response. + */ + public void setExtension(List extension) { + this.extension = extension; + } + + /** + * Gets the selection function specified in the serialisation response. + * + * @return The selection function specified in the serialisation response. + */ + public String getSelectionFunction() { + return selectionFunction; + } + + /** + * Sets the selection function specified in the serialisation response. + * + * @param selectionFunction The selection function specified in the serialisation response. + */ + public void setSelectionFunction(String selectionFunction) { + this.selectionFunction = selectionFunction; + } + + /** + * Gets the termination function specified in the serialisation response. + * + * @return The termination function specified in the serialisation response. + */ + public String getTerminationFunction() { + return terminationFunction; + } + + /** + * Sets the termination function specified in the serialisation response. + * + * @param terminationFunction The termination function specified in the serialisation response. + */ + public void setTerminationFunction(String terminationFunction) { + this.terminationFunction = terminationFunction; + } + + /** + * Gets the answer provided by the serialisation response. + * + * @return The answer provided by the serialisation response. + */ + public String getAnswer() { + return answer; + } + + /** + * Sets the answer provided by the serialisation response. + * + * @param answer The answer provided by the serialisation response. + */ + public void setAnswer(String answer) { + this.answer = answer; + } + + /** + * Gets the time taken for the serialisation operation (in seconds). + * + * @return The time taken for the serialisation operation (in seconds). + */ + public double getTime() { + return time; + } + + /** + * Sets the time taken for the serialisation operation (in seconds). + * + * @param time The time taken for the serialisation operation (in seconds). + */ + public void setTime(double time) { + this.time = time; + } + + /** + * Gets the unit time specified in the serialisation response. + * + * @return The unit time specified in the serialisation response. + */ + public String getUnit_time() { + return unit_time; + } + + /** + * Sets the unit time specified in the serialisation response. + * + * @param unit_time The unit time specified in the serialisation response. + */ + public void setUnit_time(String unit_time) { + this.unit_time = unit_time; + } + + /** + * Gets the status of the serialisation response. + * + * @return The status of the serialisation response. + */ + public String getStatus() { + return status; + } + + /** + * Sets the status of the serialisation response. + * + * @param status The status of the serialisation response. + */ + public void setStatus(String status) { + this.status = status; + } + + /** + * Sets the reply message in the serialisation response. + * + * @param reply The reply message in the serialisation response. + * @return The current instance of SerialisationResponse. + */ + public SerialisationResponse reply(String reply) { + setReply(reply); + return this; + } + + /** + * Sets the email associated with the serialisation response. + * + * @param email The email associated with the serialisation response. + * @return The current instance of SerialisationResponse. + */ + public SerialisationResponse email(String email) { + setEmail(email); + return this; + } + + /** + * Sets the number of arguments in the serialisation response. + * + * @param nr_of_arguments The number of arguments in the serialisation response. + * @return The current instance of SerialisationResponse. + */ + public SerialisationResponse nr_of_arguments(int nr_of_arguments) { + setNr_of_arguments(nr_of_arguments); + return this; + } + + /** + * Sets the attacks information in the serialisation response. + * + * @param attacks The attacks information in the serialisation response. + * @return The current instance of SerialisationResponse. + */ + public SerialisationResponse attacks(List> attacks) { + setAttacks(attacks); + return this; + } + + /** + * Sets the extension in the serialisation response. + * + * @param extension The extension in the serialisation response. + * @return The current instance of SerialisationResponse. + */ + public SerialisationResponse extension(List extension) { + setExtension(extension); + return this; + } + + /** + * Sets the selection function specified in the serialisation response. + * + * @param selectionFunction The selection function specified in the serialisation response. + * @return The current instance of SerialisationResponse. + */ + public SerialisationResponse selectionFunction(String selectionFunction) { + setSelectionFunction(selectionFunction); + return this; + } + + /** + * Sets the termination function specified in the serialisation response. + * + * @param terminationFunction The termination function specified in the serialisation response. + * @return The current instance of SerialisationResponse. + */ + public SerialisationResponse terminationFunction(String terminationFunction) { + setTerminationFunction(terminationFunction); + return this; + } + + /** + * Sets the answer provided by the serialisation response. + * + * @param answer The answer provided by the serialisation response. + * @return The current instance of SerialisationResponse. + */ + public SerialisationResponse answer(String answer) { + setAnswer(answer); + return this; + } + + /** + * Sets the time taken for the serialisation operation (in seconds). + * + * @param time The time taken for the serialisation operation (in seconds). + * @return The current instance of SerialisationResponse. + */ + public SerialisationResponse time(int time) { + setTime(time); + return this; + } + + /** + * Sets the status of the serialisation response. + * + * @param status The status of the serialisation response. + * @return The current instance of SerialisationResponse. + */ + public SerialisationResponse status(String status) { + setStatus(status); + return this; + } + + @Override + public boolean equals(Object o) { + if (o == this) + return true; + if (!(o instanceof SerialisationResponse)) { + return false; + } + SerialisationResponse tweetyResponse = (SerialisationResponse) o; + return Objects.equals(reply, tweetyResponse.reply) && Objects.equals(email, tweetyResponse.email) + && nr_of_arguments == tweetyResponse.nr_of_arguments && Objects.equals(attacks, tweetyResponse.attacks) && Objects.equals(extension, tweetyResponse.extension) + && Objects.equals(selectionFunction, tweetyResponse.selectionFunction) && Objects.equals(terminationFunction, tweetyResponse.terminationFunction) + && Objects.equals(answer, tweetyResponse.answer) && time == tweetyResponse.time + && Objects.equals(status, tweetyResponse.status); + } + + @Override + public int hashCode() { + return Objects.hash(reply, email, nr_of_arguments, attacks, selectionFunction, terminationFunction, answer, time, status); + } + + @Override + public String toString() { + return "{" + + " reply='" + getReply() + "'" + + ", email='" + getEmail() + "'" + + ", nr_of_arguments='" + getNr_of_arguments() + "'" + + ", attacks='" + getAttacks() + "'" + + ", extension='" + getExtension() + "'" + + ", selectionFunction='" + getSelectionFunction() + "'" + + ", terminationFunction='" + getTerminationFunction() + "'" + + ", answer='" + getAnswer() + "'" + + ", time='" + getTime() + "'" + + ", status='" + getStatus() + "'" + + "}"; + } + +} \ No newline at end of file diff --git a/org-tweetyproject-web/src/test/java/org/tweetyproject/web/services/RequestControllerSerialisationTest.java b/org-tweetyproject-web/src/test/java/org/tweetyproject/web/services/RequestControllerSerialisationTest.java new file mode 100644 index 000000000..2290e2cbe --- /dev/null +++ b/org-tweetyproject-web/src/test/java/org/tweetyproject/web/services/RequestControllerSerialisationTest.java @@ -0,0 +1,338 @@ +/* + * This file is part of "TweetyProject", a collection of Java libraries for + * logical aspects of artificial intelligence and knowledge representation. + * + * TweetyProject is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Copyright 2026 The TweetyProject Team + */ +package org.tweetyproject.web.services; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.http.MediaType; +import org.springframework.test.web.servlet.MockMvc; +import org.tweetyproject.arg.dung.semantics.Semantics; +import org.tweetyproject.web.services.bipolar.BipolarSemantics; + +import java.util.stream.Stream; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + + +/** + * @author Lars Bengel + */ +@SpringBootTest +@AutoConfigureMockMvc +class RequestControllerSerialisationTest { + @Autowired + private MockMvc mvc; + + @Test + public void getInfos() throws Exception { + var post = post("/serialisation").contentType(MediaType.APPLICATION_JSON) + // language=JSON + .content(""" + { + "cmd": "info" + } + """); + + mvc.perform(post).andExpect(status().isOk()) + // language=JSON + .andExpect(content().json(""" + { + "reply": "info", + "email": null, + "backend_timeout": 600, + "selectionFunctions": [ + "ADM","UC","GR" + ], + "terminationFunctions": [ + "ADM","CO","UC","PR","ST" + ], + "commands": [ + "get_reduct", + "is_terminal", + "get_selection", + "get_models", + "get_sequences" + ] + } + """, true)); + } + + @Test + public void getReduct() throws Exception { + var post = post("/serialisation").contentType(MediaType.APPLICATION_JSON) + // language=JSON + .content(""" + { + "cmd": "get_reduct", + "nr_of_arguments": 4, + "attacks": [[1, 2],[2,3],[3,4],[4,3]], + "extension": [1], + "timeout": 10, + "unit_timeout": "s" + } + """); + + mvc.perform(post).andExpect(status().isOk()) + // language=JSON + .andExpect(content().json(""" + { + "reply": "get_reduct", + "email": null, + "nr_of_arguments": 4, + "attacks": [ + [ + 1, + 2 + ], + [ + 2, + 3 + ], + [ + 3, + 4 + ], + [ + 4, + 3 + ] + ], + "extension": [1], + "selectionFunction": null, + "terminationFunction": null, + "answer": "<{ 3, 4 },[(3,4), (4,3)]>", + "time": 0, + "unit_time": "s", + "status": "SUCCESS" + } + """, true)); + } + + @Test + public void getSelection() throws Exception { + var post = post("/serialisation").contentType(MediaType.APPLICATION_JSON) + // language=JSON + .content(""" + { + "cmd": "get_selection", + "nr_of_arguments": 4, + "attacks": [[1, 2],[2,3],[3,4],[4,3]], + "selectionFunction": "UC", + "timeout": 10, + "unit_timeout": "s" + } + """); + + mvc.perform(post).andExpect(status().isOk()) + // language=JSON + .andExpect(content().json(""" + { + "reply": "get_selection", + "email": null, + "nr_of_arguments": 4, + "attacks": [ + [ + 1, + 2 + ], + [ + 2, + 3 + ], + [ + 3, + 4 + ], + [ + 4, + 3 + ] + ], + "extension": null, + "selectionFunction": "UC", + "terminationFunction": null, + "answer": "[{1}, {4}]", + "time": 0, + "unit_time": "s", + "status": "SUCCESS" + } + """, true)); + } + + @Test + public void isTerminal() throws Exception { + var post = post("/serialisation").contentType(MediaType.APPLICATION_JSON) + // language=JSON + .content(""" + { + "cmd": "is_terminal", + "nr_of_arguments": 4, + "attacks": [[1, 2],[2,3],[3,4],[4,3]], + "terminationFunction": "UC", + "timeout": 10, + "unit_timeout": "s" + } + """); + + mvc.perform(post).andExpect(status().isOk()) + // language=JSON + .andExpect(content().json(""" + { + "reply": "is_terminal", + "email": null, + "nr_of_arguments": 4, + "attacks": [ + [ + 1, + 2 + ], + [ + 2, + 3 + ], + [ + 3, + 4 + ], + [ + 4, + 3 + ] + ], + "extension": null, + "selectionFunction": null, + "terminationFunction": "UC", + "answer": "false", + "time": 0, + "unit_time": "s", + "status": "SUCCESS" + } + """, true)); + } + + @Test + public void getModels() throws Exception { + var post = post("/serialisation").contentType(MediaType.APPLICATION_JSON) + // language=JSON + .content(""" + { + "cmd": "get_models", + "nr_of_arguments": 4, + "attacks": [[1, 2],[2,3],[3,4],[4,3]], + "selectionFunction": "ADM", + "terminationFunction": "PR", + "timeout": 10, + "unit_timeout": "s" + } + """); + + mvc.perform(post).andExpect(status().isOk()) + // language=JSON + .andExpect(content().json(""" + { + "reply": "get_models", + "email": null, + "nr_of_arguments": 4, + "attacks": [ + [ + 1, + 2 + ], + [ + 2, + 3 + ], + [ + 3, + 4 + ], + [ + 4, + 3 + ] + ], + "extension": null, + "selectionFunction": "ADM", + "terminationFunction": "PR", + "answer": "[{1,3}, {1,4}]", + "time": 0, + "unit_time": "s", + "status": "SUCCESS" + } + """, true)); + } + + @Test + public void getSequences() throws Exception { + var post = post("/serialisation").contentType(MediaType.APPLICATION_JSON) + // language=JSON + .content(""" + { + "cmd": "get_sequences", + "nr_of_arguments": 4, + "attacks": [[1, 2],[2,3],[3,4],[4,3]], + "selectionFunction": "UC", + "terminationFunction": "UC", + "timeout": 10, + "unit_timeout": "s" + } + """); + + mvc.perform(post).andExpect(status().isOk()) + // language=JSON + .andExpect(content().json(""" + { + "reply": "get_sequences", + "email": null, + "nr_of_arguments": 4, + "attacks": [ + [ + 1, + 2 + ], + [ + 2, + 3 + ], + [ + 3, + 4 + ], + [ + 4, + 3 + ] + ], + "extension": null, + "selectionFunction": "UC", + "terminationFunction": "UC", + "answer": "[({4},{1}), ({1})]", + "time": 0, + "unit_time": "s", + "status": "SUCCESS" + } + """, true)); + } +} \ No newline at end of file From 4c44c47880d568b4ef3e9c22424530821c3f5dae Mon Sep 17 00:00:00 2001 From: larsbengel <77848869+larsbengel@users.noreply.github.com> Date: Mon, 15 Jun 2026 00:28:32 +0200 Subject: [PATCH 03/14] minor bugfix --- .../web/services/RequestController.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/RequestController.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/RequestController.java index c1a48e8b0..ca609d60b 100644 --- a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/RequestController.java +++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/RequestController.java @@ -1499,36 +1499,33 @@ public Response handleRequest(@RequestBody SerialisationPost serPost) { int user_timeout = Utils.checkUserTimeout(serPost.getTimeout(), SERVICES_TIMEOUT_DUNG, unit); try { String result_str; + Long result_time; switch (cmd) { case GET_SEQUENCES -> { Future> future = executor.submit(callee); Pair, Long> result = Utils.runServicesWithTimeout(future, user_timeout, unit); result_str = result.getKey().toString(); + result_time = result.getValue(); } case GET_REDUCT -> { Future future = executor.submit(callee); Pair result = Utils.runServicesWithTimeout(future, user_timeout, unit); result_str = result.getKey().toString(); + result_time = result.getValue(); } case IS_TERMINAL -> { Future future = executor.submit(callee); Pair result = Utils.runServicesWithTimeout(future, user_timeout, unit); result_str = result.getKey().toString(); + result_time = result.getValue(); } case GET_SELECTION,GET_MODELS -> { Future>> future = executor.submit(callee); Pair>, Long> result = Utils.runServicesWithTimeout(future, user_timeout, unit); result_str = result.getKey().toString(); + result_time = result.getValue(); } default -> throw new IllegalArgumentException("unknown command " + cmd); - - /* - - */ - } - // TODO update result type; need to make distinction here i guess - Future future = executor.submit(callee); - Pair result = Utils.runServicesWithTimeout(future, user_timeout, unit); executor.shutdownNow(); reasonerResponse.setAnswer(result_str); - reasonerResponse.setTime(result.getValue()); + reasonerResponse.setTime(result_time); reasonerResponse.setStatus("SUCCESS"); } catch (TimeoutException e) { reasonerResponse.setTime(serPost.getTimeout()); From 8ea7d5219760de6964f7edee69992b3476796ca7 Mon Sep 17 00:00:00 2001 From: Lars Bengel Date: Mon, 15 Jun 2026 02:21:40 +0200 Subject: [PATCH 04/14] Experimental refactoring of RequestController --- .../web/services/RequestController.java | 1536 +++++------------ .../web/services/causal/CausalController.java | 186 ++ 2 files changed, 577 insertions(+), 1145 deletions(-) create mode 100644 org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/causal/CausalController.java diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/RequestController.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/RequestController.java index ca609d60b..935b9bb9b 100644 --- a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/RequestController.java +++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/RequestController.java @@ -18,14 +18,12 @@ */ package org.tweetyproject.web.services; -import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.LinkedList; import java.util.List; -import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; @@ -34,24 +32,34 @@ import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; +import java.util.logging.Level; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.ObjectMapper; import org.json.JSONException; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpStatus; -import org.springframework.lang.Nullable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; -import org.springframework.web.server.ResponseStatusException; +import org.tweetyproject.arg.aba.parser.AbaParser; +import org.tweetyproject.arg.aba.reasoner.GeneralAbaReasoner; +import org.tweetyproject.arg.aba.semantics.AbaExtension; +import org.tweetyproject.arg.aba.syntax.AbaTheory; +import org.tweetyproject.arg.aba.syntax.Assumption; import org.tweetyproject.arg.adf.reasoner.AbstractADFReasoner; -import org.tweetyproject.arg.adf.semantics.interpretation.Interpretation; import org.tweetyproject.arg.adf.syntax.adf.AbstractDialecticalFramework; import org.tweetyproject.arg.bipolar.reasoner.AbstractBipolarExtensionReasoner; import org.tweetyproject.arg.bipolar.syntax.BipolarArgumentationFramework; +import org.tweetyproject.arg.delp.parser.DelpParser; +import org.tweetyproject.arg.delp.reasoner.DelpReasoner; +import org.tweetyproject.arg.delp.semantics.ComparisonCriterion; +import org.tweetyproject.arg.delp.semantics.DelpAnswer; +import org.tweetyproject.arg.delp.semantics.EmptyCriterion; +import org.tweetyproject.arg.delp.semantics.GeneralizedSpecificity; +import org.tweetyproject.arg.delp.syntax.DefeasibleLogicProgram; +import org.tweetyproject.arg.dung.reasoner.AbstractExtensionReasoner; import org.tweetyproject.arg.dung.reasoner.IncompleteReasoner; +import org.tweetyproject.arg.dung.semantics.Extension; import org.tweetyproject.arg.dung.semantics.Semantics; -import org.tweetyproject.arg.dung.serialisability.semantics.SerialisationSequence; import org.tweetyproject.arg.dung.serialisability.syntax.SelectionFunction; import org.tweetyproject.arg.dung.serialisability.syntax.TerminationFunction; import org.tweetyproject.arg.dung.syntax.Argument; @@ -62,13 +70,10 @@ import org.tweetyproject.arg.prob.syntax.ProbabilisticArgumentationFramework; import org.tweetyproject.arg.rankings.reasoner.AbstractRankingReasoner; import org.tweetyproject.arg.rankings.semantics.RankingSemantics; -import org.tweetyproject.causal.parser.CausalParser; -import org.tweetyproject.causal.syntax.CausalKnowledgeBase; import org.tweetyproject.commons.BeliefSet; import org.tweetyproject.commons.Formula; import org.tweetyproject.commons.Parser; import org.tweetyproject.commons.ParserException; -import org.tweetyproject.comparator.GeneralComparator; import org.tweetyproject.logics.commons.analysis.InconsistencyMeasure; import org.tweetyproject.logics.commons.analysis.NaiveMusEnumerator; import org.tweetyproject.logics.fol.parser.FolParser; @@ -97,7 +102,6 @@ import org.tweetyproject.web.services.aba.GeneralAbaReasonerFactory; import org.tweetyproject.web.services.adf.*; import org.tweetyproject.web.services.bipolar.*; -import org.tweetyproject.web.services.causal.*; import org.tweetyproject.web.services.delp.DeLPCallee; import org.tweetyproject.web.services.delp.DeLPPost; import org.tweetyproject.web.services.delp.DeLPResponse; @@ -107,42 +111,22 @@ import org.tweetyproject.web.services.incmes.InconsistencyGetMeasuresResponse; import org.tweetyproject.web.services.incmes.InconsistencyPost; import org.tweetyproject.web.services.incmes.InconsistencyValueResponse; -import org.tweetyproject.web.services.rankings.*; import org.tweetyproject.web.services.paf.*; +import org.tweetyproject.web.services.rankings.*; import org.tweetyproject.web.services.sequenceexplanation.*; import org.tweetyproject.web.services.sequenceexplanation.SequenceExplanationPost.GetSequenceExplanationsCmd; import org.tweetyproject.web.services.sequenceexplanation.SequenceExplanationPost.SequenceExplanationCmd; import org.tweetyproject.web.services.sequenceexplanation.SequenceExplanationResponse.GetSequenceExplanationsResult; import org.tweetyproject.web.services.sequenceexplanation.SequenceExplanationResponse.SequenceExplanationResult; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.RequestBody; -import org.tweetyproject.arg.aba.parser.AbaParser; -import org.tweetyproject.arg.aba.reasoner.GeneralAbaReasoner; -import org.tweetyproject.arg.aba.semantics.AbaExtension; -import org.tweetyproject.arg.aba.syntax.AbaTheory; -import org.tweetyproject.arg.aba.syntax.Assumption; -import org.tweetyproject.arg.delp.parser.DelpParser; -import org.tweetyproject.arg.delp.reasoner.DelpReasoner; -import org.tweetyproject.arg.delp.semantics.ComparisonCriterion; -import org.tweetyproject.arg.delp.semantics.DelpAnswer; -import org.tweetyproject.arg.delp.semantics.EmptyCriterion; -import org.tweetyproject.arg.delp.semantics.GeneralizedSpecificity; -import org.tweetyproject.arg.delp.syntax.DefeasibleLogicProgram; -import org.tweetyproject.arg.dung.reasoner.AbstractExtensionReasoner; -import org.tweetyproject.arg.dung.semantics.Extension; +import org.tweetyproject.web.services.serialisation.*; import javafx.util.Pair; -import org.tweetyproject.web.services.serialisation.*; import javax.validation.Valid; -import java.util.logging.Level; - -import static org.tweetyproject.web.services.causal.CausalReasonerResponse.Status.SUCCESS; -import static org.tweetyproject.web.services.causal.CausalReasonerResponse.Status.TIMEOUT; /** - * handles HTTP POST requests at the provided endpoints + * Handles HTTP POST requests for all TweetyProject web service endpoints. */ @RestController public class RequestController { @@ -151,316 +135,197 @@ public class RequestController { private final int SERVICES_TIMEOUT_DELP = 600; private final int SERVICES_TIMEOUT_INCMES = 300; private final int SERVICES_TIMEOUT_SEQUENCE_EXPLANATION = 300; - private final int SERVICES_TIMEOUT_CAUSAL = 300; private final SequenceExplanationService sequenceExplanationService; - private final ObjectMapper objectMapper; - private final CausalReasonerService causalReasonerService; - /** - * Constructor for causal reasoner service - * @param sequenceExplanationService the sequence explanation service - * @param objectMapper the object mapper - * @param causalReasonerService the causal reasoner service - */ @Autowired - public RequestController(SequenceExplanationService sequenceExplanationService, - ObjectMapper objectMapper, - CausalReasonerService causalReasonerService) { + public RequestController(SequenceExplanationService sequenceExplanationService) { this.sequenceExplanationService = sequenceExplanationService; - this.objectMapper = objectMapper; - this.causalReasonerService = causalReasonerService; } + /** Holds the outcome of a timed callee execution. */ + private static final class ExecutionResult { + final String answer; + final double time; + final String status; + + ExecutionResult(String answer, double time, String status) { + this.answer = answer; + this.time = time; + this.status = status; + } + } + + /** + * Submits {@code callee} to a single-threaded executor, waits up to {@code userTimeout}, + * and returns an {@link ExecutionResult} with answer/time/status filled in. + */ + @SuppressWarnings({"rawtypes", "unchecked"}) + private static ExecutionResult runCallee(Callee callee, int userTimeout, double requestTimeout, TimeUnit unit) { + ExecutorService executor = Executors.newSingleThreadExecutor(); + try { + Future future = executor.submit((Callable) callee); + Pair result = Utils.runServicesWithTimeout(future, userTimeout, unit); + executor.shutdownNow(); + return new ExecutionResult(result.getKey().toString(), (double) result.getValue(), "SUCCESS"); + } catch (TimeoutException e) { + executor.shutdownNow(); + return new ExecutionResult(null, requestTimeout, "TIMEOUT"); + } catch (Exception e) { + executor.shutdownNow(); + return new ExecutionResult(null, 0.0, "Error"); + } + } + + // ── ABA ────────────────────────────────────────────────────────────────── -/** - * Handles HTTP POST requests at the endpoint "/aba". Parses and processes the incoming - * JSON payload to perform various ABA reasoning commands. - * Supported commands are: - * - get_models: Return all models for a given semantics and beliefbase - * - get_model: Return some model for a given semantics and beliefbase - * - query: Query an assumption - * - semantics: Return supported semantics - * - * @param AbaReasonerPost The request payload containing information for ABA reasoning. - * @return A Response object containing the result of the ABA reasoning operation. - * @throws ParserException If there is an error while parsing the input data. - * @throws IOException If there is an error reading or writing data. - * @throws JSONException If there is an error with JSON processing. - * @throws org.codehaus.jettison.json.JSONException If there is an error with Jettison JSON processing. - */ @PostMapping(value = "/aba", produces = "application/json", consumes = "application/json") @ResponseBody - public Response handleRequest( - @RequestBody AbaReasonerPost AbaReasonerPost) throws ParserException, IOException, JSONException, org.codehaus.jettison.json.JSONException { + public Response handleRequest(@RequestBody AbaReasonerPost post) + throws ParserException, IOException, JSONException, org.codehaus.jettison.json.JSONException { - LoggerUtil.logger.info(String.format("User: %s Command: %s", AbaReasonerPost.getEmail(), AbaReasonerPost.getCmd())); - if (AbaReasonerPost.getCmd().equals("semantics")) { - return handleGetSemantics(AbaReasonerPost); - } - Callee callee = null; - SatSolver.setDefaultSolver(new Sat4jSolver()); - if (AbaReasonerPost.getKb_format().equals("pl")) { - AbaParser parser1 = new AbaParser(new PlParser()); - Assumption a = new Assumption<>(new Proposition(AbaReasonerPost.getQuery_assumption())); - AbaTheory abat1 = null; - try { - abat1 = parser1.parseBeliefBase(AbaReasonerPost.getKb()); - } catch (FileNotFoundException e) { - LoggerUtil.logger.log(Level.SEVERE,(String.format("Error while parsing the Beliefbase: %s", e.getClass().getSimpleName()))); - - e.printStackTrace(); - } catch (ParserException e) { - LoggerUtil.logger.log(Level.SEVERE,(String.format("Error while parsing the Beliefbase: %s", e.getClass().getSimpleName()))); - - e.printStackTrace(); - } catch (IOException e) { - LoggerUtil.logger.log(Level.SEVERE,(String.format("Error while parsing the Beliefbase: %s", e.getClass().getSimpleName()))); - e.printStackTrace(); - } - - GeneralAbaReasoner r1 = GeneralAbaReasonerFactory - .getReasoner(GeneralAbaReasonerFactory.Semantics.getSemantics(AbaReasonerPost.getSemantics())); - callee = AbaReasonerCalleeFactory - .getCallee(AbaReasonerCalleeFactory.Command.getCommand(AbaReasonerPost.getCmd()), r1, abat1,a); - } + LoggerUtil.logger.info(String.format("User: %s Command: %s", post.getEmail(), post.getCmd())); + if (post.getCmd().equals("semantics")) + return handleGetSemantics(post); - if (AbaReasonerPost.getKb_format().equals("fol")) { - FolParser folparser = new FolParser(); - FolSignature sig = folparser.parseSignature(AbaReasonerPost.getFol_signature()); - AbaParser parser1 = new AbaParser(folparser); - Assumption a = new Assumption<>(folparser.parseFormula(AbaReasonerPost.getQuery_assumption())); - parser1.setSymbolComma(";"); - AbaTheory abat1 = null; - folparser.setSignature(sig); - try { - abat1 = parser1.parseBeliefBase(AbaReasonerPost.getKb()); - System.out.println("Parsed belief base: " + abat1); - } catch (FileNotFoundException e) { - LoggerUtil.logger.log(Level.SEVERE,(String.format("Error while parsing the Beliefbase: %s", e.getClass().getSimpleName()))); - e.printStackTrace(); - } catch (ParserException e) { - LoggerUtil.logger.log(Level.SEVERE,(String.format("Error while parsing the Beliefbase: %s", e.getClass().getSimpleName()))); - - e.printStackTrace(); - } catch (IOException e) { - LoggerUtil.logger.log(Level.SEVERE,(String.format("Error while parsing the Beliefbase: %s", e.getClass().getSimpleName()))); - - e.printStackTrace(); - } - - GeneralAbaReasoner r1 = GeneralAbaReasonerFactory - .getReasoner(GeneralAbaReasonerFactory.Semantics.getSemantics(AbaReasonerPost.getSemantics())); - - try { - callee = AbaReasonerCalleeFactory - .getCallee(AbaReasonerCalleeFactory.Command.getCommand(AbaReasonerPost.getCmd()), r1, abat1,a); - } - catch (Exception e) { - LoggerUtil.logger.log(Level.SEVERE,(String.format("Error while creating ABAReasonerCallee:%s", e.getClass().getSimpleName()))); - } + SatSolver.setDefaultSolver(new Sat4jSolver()); + Callee callee = null; + if (post.getKb_format().equals("pl")) { + AbaParser parser = new AbaParser<>(new PlParser()); + Assumption assumption = new Assumption<>(new Proposition(post.getQuery_assumption())); + AbaTheory theory = null; + try { + theory = parser.parseBeliefBase(post.getKb()); + } catch (ParserException | IOException e) { + LoggerUtil.logger.log(Level.SEVERE, String.format("Error while parsing the Beliefbase: %s", e.getClass().getSimpleName())); } + GeneralAbaReasoner reasoner = GeneralAbaReasonerFactory.getReasoner( + GeneralAbaReasonerFactory.Semantics.getSemantics(post.getSemantics())); + callee = AbaReasonerCalleeFactory.getCallee( + AbaReasonerCalleeFactory.Command.getCommand(post.getCmd()), reasoner, theory, assumption); + } - ExecutorService executor = Executors.newSingleThreadExecutor(); - AbaReasonerResponse reasonerResponse = new AbaReasonerResponse(AbaReasonerPost.getCmd(), - AbaReasonerPost.getEmail(), AbaReasonerPost.getKb(), AbaReasonerPost.getKb_format(), - AbaReasonerPost.getFol_signature(), AbaReasonerPost.getQuery_assumption(), - AbaReasonerPost.getSemantics(), AbaReasonerPost.getTimeout(), "", 0.0, - AbaReasonerPost.getUnit_timeout(), ""); - TimeUnit unit = Utils.getTimeoutUnit(AbaReasonerPost.getUnit_timeout()); - int user_timeout = Utils.checkUserTimeout(AbaReasonerPost.getTimeout(), SERVICES_TIMEOUT_DUNG, unit); + if (post.getKb_format().equals("fol")) { + FolParser folParser = new FolParser(); + FolSignature sig = folParser.parseSignature(post.getFol_signature()); + folParser.setSignature(sig); + AbaParser parser = new AbaParser<>(folParser); + parser.setSymbolComma(";"); + Assumption assumption = new Assumption<>(folParser.parseFormula(post.getQuery_assumption())); + AbaTheory theory = null; try { - // handle timeout - LoggerUtil.logger.info(String.format("Run command \"%s\" with timeout: %s %s", AbaReasonerPost.getCmd(),user_timeout, AbaReasonerPost.getUnit_timeout())); - if (AbaReasonerPost.getCmd().equals("get_models") || AbaReasonerPost.getCmd().equals("get_model")) { - - Future>> future = executor.submit(callee); - Pair>, Long> result = Utils.runServicesWithTimeout(future, - user_timeout, unit); - LoggerUtil.logger.info(String.format("Execution of command \"%s\" finished after %s %s ", AbaReasonerPost.getCmd(),result.getValue(),AbaReasonerPost.getUnit_timeout())); - reasonerResponse.setTime(result.getValue()); - reasonerResponse.setAnswer(result.getKey().toString()); - reasonerResponse.setStatus("SUCCESS"); - } - else if (AbaReasonerPost.getCmd().equals("query")){ - Future future = executor.submit(callee); - Pair result = Utils.runServicesWithTimeout(future, - user_timeout, unit); - - LoggerUtil.logger.info(String.format("Execution of command \"%s\" finished after %s %s ", AbaReasonerPost.getCmd(),result.getValue(),AbaReasonerPost.getUnit_timeout())); - - reasonerResponse.setTime(result.getValue()); - reasonerResponse.setAnswer(result.getKey().toString()); - reasonerResponse.setStatus("SUCCESS"); - } - else{ - LoggerUtil.logger.log(Level.SEVERE,String.format("Command \"%s\" not found.", AbaReasonerPost.getCmd())); - Pair result = new Pair("Command not found",0 ); - System.out.println(result.getKey().toString()); - reasonerResponse.setTime(result.getValue()); - reasonerResponse.setAnswer(result.getKey().toString()); - reasonerResponse.setStatus("ERROR"); - } - - executor.shutdownNow(); - } catch (TimeoutException e) { - LoggerUtil.logger.info(String.format("Execution of command \"%s\" reached timeout of %s %s and was aborted.", AbaReasonerPost.getCmd(),AbaReasonerPost.getTimeout(),AbaReasonerPost.getUnit_timeout())); - reasonerResponse.setTime(AbaReasonerPost.getTimeout()); - reasonerResponse.setAnswer(null); - reasonerResponse.setStatus("TIMEOUT"); - executor.shutdownNow(); + theory = parser.parseBeliefBase(post.getKb()); + } catch (ParserException | IOException e) { + LoggerUtil.logger.log(Level.SEVERE, String.format("Error while parsing the Beliefbase: %s", e.getClass().getSimpleName())); + } + GeneralAbaReasoner reasoner = GeneralAbaReasonerFactory.getReasoner( + GeneralAbaReasonerFactory.Semantics.getSemantics(post.getSemantics())); + try { + callee = AbaReasonerCalleeFactory.getCallee( + AbaReasonerCalleeFactory.Command.getCommand(post.getCmd()), reasoner, theory, assumption); } catch (Exception e) { - LoggerUtil.logger.log(Level.SEVERE,(String.format("Error while running command \"%s\": %s",AbaReasonerPost.getCmd(), e.getClass().getSimpleName()))); - reasonerResponse.setTime(0.0); - reasonerResponse.setAnswer(null); - reasonerResponse.setStatus("Error"); - - executor.shutdownNow(); + LoggerUtil.logger.log(Level.SEVERE, String.format("Error while creating ABAReasonerCallee: %s", e.getClass().getSimpleName())); } - return reasonerResponse; + } + + AbaReasonerResponse response = new AbaReasonerResponse(post.getCmd(), post.getEmail(), post.getKb(), + post.getKb_format(), post.getFol_signature(), post.getQuery_assumption(), + post.getSemantics(), post.getTimeout(), "", 0.0, post.getUnit_timeout(), ""); + + if (!post.getCmd().equals("get_models") && !post.getCmd().equals("get_model") && !post.getCmd().equals("query")) { + LoggerUtil.logger.log(Level.SEVERE, String.format("Command \"%s\" not found.", post.getCmd())); + response.setAnswer("Command not found"); + response.setStatus("ERROR"); + return response; + } + + TimeUnit unit = Utils.getTimeoutUnit(post.getUnit_timeout()); + int userTimeout = Utils.checkUserTimeout(post.getTimeout(), SERVICES_TIMEOUT_DUNG, unit); + LoggerUtil.logger.info(String.format("Run command \"%s\" with timeout: %s %s", post.getCmd(), userTimeout, post.getUnit_timeout())); + ExecutionResult r = runCallee(callee, userTimeout, post.getTimeout(), unit); + response.setAnswer(r.answer); + response.setTime(r.time); + response.setStatus(r.status); + LoggerUtil.logger.info(String.format("Command \"%s\" finished with status: %s", post.getCmd(), r.status)); + return response; } - /** - * Handles HTTP POST requests for Dung Reasoner operations. - * - *

This method processes requests with the endpoint "/dung" that have the specified content types - * for both request and response. It takes a DungReasonerPost object as the request body and returns - * a Response object as the response body.

- * - *

The method checks the command (cmd) from the DungReasonerPost object and performs different - * operations based on the command. If the command is "info," it delegates the request to the getInfo - * method. If the command is "get_models" or "get_model," it processes the request using the DungTheory, - * AbstractExtensionReasoner, and other components. The result includes information about the execution - * time, answer, and status, which is encapsulated in a DungReasonerResponse object.

- * - *

In case of a timeout during execution, the method sets the response status to "TIMEOUT" and includes - * the specified timeout duration. If any other exception occurs, the response status is set to "Error," - * and the method provides a generic response with a time of 0.0 and a null answer.

- * - *

If the command is not recognized or not applicable, the method returns a default DungReasonerResponse.

- * - * @param dungReasonerPost The DungReasonerPost object representing the request payload. - * @return A Response object representing the response payload. - */ + // ── Dung ───────────────────────────────────────────────────────────────── + @PostMapping(value = "/dung", produces = "application/json", consumes = "application/json") @ResponseBody - public Response handleRequest( - @RequestBody DungReasonerPost dungReasonerPost) { - if (dungReasonerPost.getCmd().equals("info")) - return (Response) getInfo(dungReasonerPost); - - if (dungReasonerPost.getCmd().equals("get_models") || dungReasonerPost.getCmd().equals("get_model") || dungReasonerPost.getCmd().equals("get_credulous") || dungReasonerPost.getCmd().equals("get_skeptical")) { - DungTheory dungTheory = AbstractExtensionReasonerFactory.getDungTheory(dungReasonerPost.getNr_of_arguments(), - dungReasonerPost.getAttacks()); - ExecutorService executor = Executors.newSingleThreadExecutor(); - DungReasonerResponse reasonerResponse = new DungReasonerResponse(dungReasonerPost.getCmd(), - dungReasonerPost.getEmail(), dungReasonerPost.getNr_of_arguments(), dungReasonerPost.getAttacks(), - dungReasonerPost.getSemantics(), dungReasonerPost.getSolver(), null, 0, - dungReasonerPost.getUnit_timeout(), "ERRORs"); - TimeUnit unit = Utils.getTimeoutUnit(dungReasonerPost.getUnit_timeout()); - AbstractExtensionReasoner reasoner = AbstractExtensionReasonerFactory.getReasoner( - Semantics.getSemantics(dungReasonerPost.getSemantics())); - Callee callee = DungReasonerCalleeFactory.getCallee( - Command.getCommand(dungReasonerPost.getCmd()), reasoner, dungTheory); - int user_timeout = Utils.checkUserTimeout(dungReasonerPost.getTimeout(), SERVICES_TIMEOUT_DUNG, unit); - try { - // handle timeout - Future>> future = executor.submit(callee); - Pair>, Long> result = Utils.runServicesWithTimeout(future, - user_timeout, unit); - executor.shutdownNow(); - reasonerResponse.setTime(result.getValue()); - reasonerResponse.setAnswer(result.getKey().toString()); - reasonerResponse.setStatus("SUCCESS"); - } catch (TimeoutException e) { - reasonerResponse.setTime(dungReasonerPost.getTimeout()); - reasonerResponse.setAnswer(null); - reasonerResponse.setStatus("TIMEOUT"); - executor.shutdownNow(); - } catch (Exception e) { - reasonerResponse.setTime(0.0); - reasonerResponse.setAnswer(null); - reasonerResponse.setStatus("Error"); + public Response handleRequest(@RequestBody DungReasonerPost post) { + if (post.getCmd().equals("info")) + return getInfo(post); - executor.shutdownNow(); - } - return reasonerResponse; - } else { + Command cmd = Command.getCommand(post.getCmd()); + if (cmd == null) return new DungReasonerResponse(); - } + + DungTheory theory = AbstractExtensionReasonerFactory.getDungTheory(post.getNr_of_arguments(), post.getAttacks()); + AbstractExtensionReasoner reasoner = AbstractExtensionReasonerFactory.getReasoner(Semantics.getSemantics(post.getSemantics())); + Callee callee = DungReasonerCalleeFactory.getCallee(cmd, reasoner, theory); + TimeUnit unit = Utils.getTimeoutUnit(post.getUnit_timeout()); + int userTimeout = Utils.checkUserTimeout(post.getTimeout(), SERVICES_TIMEOUT_DUNG, unit); + + DungReasonerResponse response = new DungReasonerResponse(post.getCmd(), post.getEmail(), + post.getNr_of_arguments(), post.getAttacks(), post.getSemantics(), post.getSolver(), + null, 0, post.getUnit_timeout(), "ERROR"); + ExecutionResult r = runCallee(callee, userTimeout, post.getTimeout(), unit); + response.setAnswer(r.answer); + response.setTime(r.time); + response.setStatus(r.status); + return response; } - /** - * Handles HTTP POST requests for Dung Reasoner operations. - * - *

This method processes requests with the endpoint "/dung" that have the specified content types - * for both request and response. It takes a DungReasonerPost object as the request body and returns - * a Response object as the response body.

- * - *

The method checks the command (cmd) from the DungReasonerPost object and performs different - * operations based on the command. If the command is "info," it delegates the request to the getInfo - * method. If the command is "get_models" or "get_model," it processes the request using the DungTheory, - * AbstractExtensionReasoner, and other components. The result includes information about the execution - * time, answer, and status, which is encapsulated in a DungReasonerResponse object.

- * - *

In case of a timeout during execution, the method sets the response status to "TIMEOUT" and includes - * the specified timeout duration. If any other exception occurs, the response status is set to "Error," - * and the method provides a generic response with a time of 0.0 and a null answer.

- * - *

If the command is not recognized or not applicable, the method returns a default DungReasonerResponse.

- * - * @param iafReasonerPost The DungReasonerPost object representing the request payload. - * @return A Response object representing the response payload. - */ + @PostMapping(value = "/info", produces = "application/json") + @ResponseBody + public DungServicesInfoResponse getInfo(@RequestBody DungReasonerPost post) { + DungServicesInfoResponse response = new DungServicesInfoResponse(); + response.setReply("info"); + response.setEmail(post.getEmail()); + response.setBackend_timeout(SERVICES_TIMEOUT_DUNG); + ArrayList semantics_ids = new ArrayList<>(); + for (Semantics s : AbstractExtensionReasonerFactory.getSemantics()) + semantics_ids.add(s.abbreviation()); + response.setSemantics(semantics_ids); + ArrayList command_ids = new ArrayList<>(); + for (Command c : DungReasonerCalleeFactory.getCommands()) + command_ids.add(c.id); + response.setCommands(command_ids); + return response; + } + + // ── IAF ────────────────────────────────────────────────────────────────── + @PostMapping(value = "/iaf", produces = "application/json", consumes = "application/json") @ResponseBody - public Response handleRequest( - @RequestBody IafReasonerPost iafReasonerPost) { - if (iafReasonerPost.getCmd().equals("info")) - return (Response) getIafInfo(iafReasonerPost.getEmail()); - - if (iafReasonerPost.getCmd().equals("get_models_pos") || iafReasonerPost.getCmd().equals("get_credulous_pos") || iafReasonerPost.getCmd().equals("get_skeptical_pos") || iafReasonerPost.getCmd().equals("get_models_nec") || iafReasonerPost.getCmd().equals("get_credulous_nec") || iafReasonerPost.getCmd().equals("get_skeptical_nec")) { - IncompleteTheory incompleteTheory = IafReasonerFactory.getIncompleteTheory(iafReasonerPost.getNr_of_arguments(), - iafReasonerPost.getUncertainArguments(), iafReasonerPost.getDefiniteAttacks(), iafReasonerPost.getUncertainAttacks()); - ExecutorService executor = Executors.newSingleThreadExecutor(); - IafReasonerResponse reasonerResponse = new IafReasonerResponse(iafReasonerPost.getCmd(), - iafReasonerPost.getEmail(), iafReasonerPost.getNr_of_arguments(), iafReasonerPost.getUncertainArguments(), - iafReasonerPost.getDefiniteAttacks(), iafReasonerPost.getUncertainAttacks(), - iafReasonerPost.getSemantics(), iafReasonerPost.getSolver(), null, 0, - iafReasonerPost.getUnit_timeout(), "ERRORs"); - TimeUnit unit = Utils.getTimeoutUnit(iafReasonerPost.getUnit_timeout()); - IncompleteReasoner reasoner = IafReasonerFactory.getReasoner( - Semantics.getSemantics(iafReasonerPost.getSemantics())); - Callee callee = IafReasonerCalleeFactory.getCallee( - IafReasonerCalleeFactory.Command.getCommand(iafReasonerPost.getCmd()), reasoner, incompleteTheory); - int user_timeout = Utils.checkUserTimeout(iafReasonerPost.getTimeout(), SERVICES_TIMEOUT_DUNG, unit); - try { - // handle timeout - Future>> future = executor.submit(callee); - Pair>, Long> result = Utils.runServicesWithTimeout(future, - user_timeout, unit); - executor.shutdownNow(); - reasonerResponse.setTime(result.getValue()); - reasonerResponse.setAnswer(result.getKey().toString()); - reasonerResponse.setStatus("SUCCESS"); - } catch (TimeoutException e) { - reasonerResponse.setTime(iafReasonerPost.getTimeout()); - reasonerResponse.setAnswer(null); - reasonerResponse.setStatus("TIMEOUT"); - executor.shutdownNow(); - } catch (Exception e) { - reasonerResponse.setTime(0.0); - reasonerResponse.setAnswer(null); - reasonerResponse.setStatus("Error"); + public Response handleRequest(@RequestBody IafReasonerPost post) { + if (post.getCmd().equals("info")) + return getIafInfo(post.getEmail()); - executor.shutdownNow(); - } - return reasonerResponse; - } else { + IafReasonerCalleeFactory.Command cmd = IafReasonerCalleeFactory.Command.getCommand(post.getCmd()); + if (cmd == null) return new IafReasonerResponse(); - } + + IncompleteTheory theory = IafReasonerFactory.getIncompleteTheory(post.getNr_of_arguments(), + post.getUncertainArguments(), post.getDefiniteAttacks(), post.getUncertainAttacks()); + IncompleteReasoner reasoner = IafReasonerFactory.getReasoner(Semantics.getSemantics(post.getSemantics())); + Callee callee = IafReasonerCalleeFactory.getCallee(cmd, reasoner, theory); + TimeUnit unit = Utils.getTimeoutUnit(post.getUnit_timeout()); + int userTimeout = Utils.checkUserTimeout(post.getTimeout(), SERVICES_TIMEOUT_DUNG, unit); + + IafReasonerResponse response = new IafReasonerResponse(post.getCmd(), post.getEmail(), + post.getNr_of_arguments(), post.getUncertainArguments(), post.getDefiniteAttacks(), + post.getUncertainAttacks(), post.getSemantics(), post.getSolver(), + null, 0, post.getUnit_timeout(), "ERROR"); + ExecutionResult r = runCallee(callee, userTimeout, post.getTimeout(), unit); + response.setAnswer(r.answer); + response.setTime(r.time); + response.setStatus(r.status); + return response; } private IafServicesInfoResponse getIafInfo(String email) { @@ -468,91 +333,44 @@ private IafServicesInfoResponse getIafInfo(String email) { response.setReply("info"); response.setEmail(email); response.setBackend_timeout(SERVICES_TIMEOUT_DUNG); - var sem = IafReasonerFactory.getSemantics(); - ArrayList semantics_ids = new ArrayList(); - for (var s : sem) { + ArrayList semantics_ids = new ArrayList<>(); + for (var s : IafReasonerFactory.getSemantics()) semantics_ids.add(s.abbreviation()); - } response.setSemantics(semantics_ids); - - IafReasonerCalleeFactory.Command[] com = IafReasonerCalleeFactory.getCommands(); - ArrayList command_ids = new ArrayList(); - for (var c : com) { + ArrayList command_ids = new ArrayList<>(); + for (var c : IafReasonerCalleeFactory.getCommands()) command_ids.add(c.id); - } response.setCommands(command_ids); - return response; } - /** - * Handles HTTP POST requests for Ranking Reasoner operations. - * - *

This method processes requests with the endpoint "/rankings" that have the specified content types - * for both request and response. It takes a DungReasonerPost object as the request body and returns - * a Response object as the response body.

- * - *

The method checks the command (cmd) from the DungReasonerPost object and performs different - * operations based on the command. If the command is "info," it delegates the request to the getInfo - * method. If the command is "get_models" or "get_model," it processes the request using the DungTheory, - * AbstractRankingReasoner, and other components. The result includes information about the execution - * time, answer, and status, which is encapsulated in a DungReasonerResponse object.

- * - *

In case of a timeout during execution, the method sets the response status to "TIMEOUT" and includes - * the specified timeout duration. If any other exception occurs, the response status is set to "Error," - * and the method provides a generic response with a time of 0.0 and a null answer.

- * - *

If the command is not recognized or not applicable, the method returns a default DungReasonerResponse.

- * - * @param rankingReasonerPost The DungReasonerPost object representing the request payload. - * @return A Response object representing the response payload. - */ + // ── Rankings ───────────────────────────────────────────────────────────── + @PostMapping(value = "/rankings", produces = "application/json", consumes = "application/json") @ResponseBody - public Response handleRequest( - @RequestBody RankingReasonerPost rankingReasonerPost) { - if (rankingReasonerPost.getCmd().equals("info")) - return (Response) getRankingInfo(rankingReasonerPost.getEmail()); - - if (rankingReasonerPost.getCmd().equals("get_model")) { - DungTheory dungTheory = AbstractExtensionReasonerFactory.getDungTheory(rankingReasonerPost.getNr_of_arguments(), - rankingReasonerPost.getAttacks()); - ExecutorService executor = Executors.newSingleThreadExecutor(); - RankingReasonerResponse reasonerResponse = new RankingReasonerResponse(rankingReasonerPost.getCmd(), - rankingReasonerPost.getEmail(), rankingReasonerPost.getNr_of_arguments(), rankingReasonerPost.getAttacks(), - rankingReasonerPost.getSemantics(), AbstractRankingReasonerFactory.getRankingType(rankingReasonerPost.getSemantics()), rankingReasonerPost.getSolver(), null, 0, - rankingReasonerPost.getUnit_timeout(), "ERRORs"); - TimeUnit unit = Utils.getTimeoutUnit(rankingReasonerPost.getUnit_timeout()); - AbstractRankingReasoner reasoner = AbstractRankingReasonerFactory.getReasoner( - RankingSemantics.getSemantics(rankingReasonerPost.getSemantics())); - Callee callee = RankingReasonerCalleeFactory.getCallee( - RankingReasonerCalleeFactory.Command.getCommand(rankingReasonerPost.getCmd()), reasoner, dungTheory); - int user_timeout = Utils.checkUserTimeout(rankingReasonerPost.getTimeout(), SERVICES_TIMEOUT_DUNG, unit); - try { - // handle timeout - Future> future = executor.submit(callee); - Pair, Long> result = Utils.runServicesWithTimeout(future, - user_timeout, unit); - executor.shutdownNow(); - reasonerResponse.setTime(result.getValue()); - reasonerResponse.setAnswer(result.getKey().toString()); - reasonerResponse.setStatus("SUCCESS"); - } catch (TimeoutException e) { - reasonerResponse.setTime(rankingReasonerPost.getTimeout()); - reasonerResponse.setAnswer(null); - reasonerResponse.setStatus("TIMEOUT"); - executor.shutdownNow(); - } catch (Exception e) { - reasonerResponse.setTime(0.0); - reasonerResponse.setAnswer(null); - reasonerResponse.setStatus("Error"); + public Response handleRequest(@RequestBody RankingReasonerPost post) { + if (post.getCmd().equals("info")) + return getRankingInfo(post.getEmail()); - executor.shutdownNow(); - } - return reasonerResponse; - } else { + RankingReasonerCalleeFactory.Command cmd = RankingReasonerCalleeFactory.Command.getCommand(post.getCmd()); + if (cmd == null) return new RankingReasonerResponse(); - } + + DungTheory theory = AbstractExtensionReasonerFactory.getDungTheory(post.getNr_of_arguments(), post.getAttacks()); + AbstractRankingReasoner reasoner = AbstractRankingReasonerFactory.getReasoner(RankingSemantics.getSemantics(post.getSemantics())); + Callee callee = RankingReasonerCalleeFactory.getCallee(cmd, reasoner, theory); + TimeUnit unit = Utils.getTimeoutUnit(post.getUnit_timeout()); + int userTimeout = Utils.checkUserTimeout(post.getTimeout(), SERVICES_TIMEOUT_DUNG, unit); + + RankingReasonerResponse response = new RankingReasonerResponse(post.getCmd(), post.getEmail(), + post.getNr_of_arguments(), post.getAttacks(), post.getSemantics(), + AbstractRankingReasonerFactory.getRankingType(post.getSemantics()), + post.getSolver(), null, 0, post.getUnit_timeout(), "ERROR"); + ExecutionResult r = runCallee(callee, userTimeout, post.getTimeout(), unit); + response.setAnswer(r.answer); + response.setTime(r.time); + response.setStatus(r.status); + return response; } private RankingServicesInfoResponse getRankingInfo(String email) { @@ -560,90 +378,44 @@ private RankingServicesInfoResponse getRankingInfo(String email) { response.setReply("info"); response.setEmail(email); response.setBackend_timeout(SERVICES_TIMEOUT_DUNG); - var sem = AbstractRankingReasonerFactory.getSemantics(); - ArrayList semantics_ids = new ArrayList(); - for (var s : sem) { + ArrayList semantics_ids = new ArrayList<>(); + for (var s : AbstractRankingReasonerFactory.getSemantics()) semantics_ids.add(s.getId()); - } response.setSemantics(semantics_ids); - - RankingReasonerCalleeFactory.Command[] com = RankingReasonerCalleeFactory.getCommands(); - ArrayList command_ids = new ArrayList(); - for (var c : com) { + ArrayList command_ids = new ArrayList<>(); + for (var c : RankingReasonerCalleeFactory.getCommands()) command_ids.add(c.id); - } response.setCommands(command_ids); - return response; } - /** - * Handles HTTP POST requests for ADF Reasoner operations. - * - *

This method processes requests with the endpoint "/dung" that have the specified content types - * for both request and response. It takes a AdfReasonerPost object as the request body and returns - * a Response object as the response body.

- * - *

The method checks the command (cmd) from the AdfReasonerPost object and performs different - * operations based on the command. If the command is "info," it delegates the request to the getInfo - * method. If the command is "get_models" or "get_model," it processes the request using the ADF, - * AbstractExtensionReasoner, and other components. The result includes information about the execution - * time, answer, and status, which is encapsulated in a DungReasonerResponse object.

- * - *

In case of a timeout during execution, the method sets the response status to "TIMEOUT" and includes - * the specified timeout duration. If any other exception occurs, the response status is set to "Error," - * and the method provides a generic response with a time of 0.0 and a null answer.

- * - *

If the command is not recognized or not applicable, the method returns a default DungReasonerResponse.

- * - * @param adfReasonerPost The DungReasonerPost object representing the request payload. - * @return A Response object representing the response payload. - */ + // ── ADF ────────────────────────────────────────────────────────────────── + @PostMapping(value = "/adf", produces = "application/json", consumes = "application/json") @ResponseBody - public Response handleRequest( - @RequestBody AdfReasonerPost adfReasonerPost) { - if (adfReasonerPost.getCmd().equals("info")) - return (Response) getAdfInfo(adfReasonerPost.getEmail()); + public Response handleRequest(@RequestBody AdfReasonerPost post) { + if (post.getCmd().equals("info")) + return getAdfInfo(post.getEmail()); - if (adfReasonerPost.getCmd().equals("get_models") || adfReasonerPost.getCmd().equals("get_credulous") || adfReasonerPost.getCmd().equals("get_skeptical")) { - ExecutorService executor = Executors.newSingleThreadExecutor(); - AdfReasonerResponse reasonerResponse = new AdfReasonerResponse(adfReasonerPost.getCmd(), - adfReasonerPost.getEmail(), adfReasonerPost.getNr_of_arguments(), adfReasonerPost.getConditions(), - adfReasonerPost.getSemantics(), adfReasonerPost.getSolver(), null, 0, - adfReasonerPost.getUnit_timeout(), "ERRORs"); - TimeUnit unit = Utils.getTimeoutUnit(adfReasonerPost.getUnit_timeout()); - try { - AbstractDialecticalFramework adf = AbstractAdfReasonerFactory.getAdf(adfReasonerPost.getNr_of_arguments(), - adfReasonerPost.getConditions()); - AbstractADFReasoner reasoner = AbstractAdfReasonerFactory.getReasoner( - Semantics.getSemantics(adfReasonerPost.getSemantics())); - Callee callee = AdfReasonerCalleeFactory.getCallee( - AdfReasonerCalleeFactory.Command.getCommand(adfReasonerPost.getCmd()), reasoner, adf); - int user_timeout = Utils.checkUserTimeout(adfReasonerPost.getTimeout(), SERVICES_TIMEOUT_DUNG, unit); - // handle timeout - Future> future = executor.submit(callee); - Pair, Long> result = Utils.runServicesWithTimeout(future, - user_timeout, unit); - executor.shutdownNow(); - reasonerResponse.setTime(result.getValue()); - reasonerResponse.setAnswer(result.getKey().toString().replace("[","{").replace("]", "}")); - reasonerResponse.setStatus("SUCCESS"); - } catch (TimeoutException e) { - reasonerResponse.setTime(adfReasonerPost.getTimeout()); - reasonerResponse.setAnswer(null); - reasonerResponse.setStatus("TIMEOUT"); - executor.shutdownNow(); - } catch (Exception e) { - reasonerResponse.setTime(0.0); - reasonerResponse.setAnswer(null); - reasonerResponse.setStatus("Error"); - executor.shutdownNow(); - } - return reasonerResponse; - } else { + AdfReasonerCalleeFactory.Command cmd = AdfReasonerCalleeFactory.Command.getCommand(post.getCmd()); + if (cmd == null) return new AdfReasonerResponse(); - } + + AbstractDialecticalFramework adf = AbstractAdfReasonerFactory.getAdf(post.getNr_of_arguments(), post.getConditions()); + AbstractADFReasoner reasoner = AbstractAdfReasonerFactory.getReasoner(Semantics.getSemantics(post.getSemantics())); + Callee callee = AdfReasonerCalleeFactory.getCallee(cmd, reasoner, adf); + TimeUnit unit = Utils.getTimeoutUnit(post.getUnit_timeout()); + int userTimeout = Utils.checkUserTimeout(post.getTimeout(), SERVICES_TIMEOUT_DUNG, unit); + + AdfReasonerResponse response = new AdfReasonerResponse(post.getCmd(), post.getEmail(), + post.getNr_of_arguments(), post.getConditions(), post.getSemantics(), post.getSolver(), + null, 0, post.getUnit_timeout(), "ERROR"); + ExecutionResult r = runCallee(callee, userTimeout, post.getTimeout(), unit); + // ADF uses curly braces instead of square brackets in the answer format + response.setAnswer(r.answer != null ? r.answer.replace("[", "{").replace("]", "}") : null); + response.setTime(r.time); + response.setStatus(r.status); + return response; } private AdfServicesInfoResponse getAdfInfo(String email) { @@ -651,157 +423,45 @@ private AdfServicesInfoResponse getAdfInfo(String email) { response.setReply("info"); response.setEmail(email); response.setBackend_timeout(SERVICES_TIMEOUT_DUNG); - var sem = AbstractAdfReasonerFactory.getSemantics(); - ArrayList semantics_ids = new ArrayList(); - for (var s : sem) { + ArrayList semantics_ids = new ArrayList<>(); + for (var s : AbstractAdfReasonerFactory.getSemantics()) semantics_ids.add(s.abbreviation()); - } response.setSemantics(semantics_ids); - - AdfReasonerCalleeFactory.Command[] com = AdfReasonerCalleeFactory.getCommands(); - ArrayList command_ids = new ArrayList(); - for (var c : com) { + ArrayList command_ids = new ArrayList<>(); + for (var c : AdfReasonerCalleeFactory.getCommands()) command_ids.add(c.id); - } response.setCommands(command_ids); - return response; } - /** - * Handles HTTP POST requests for ping operations. - * - *

This method processes requests with the endpoint "/ping" that have the specified content type - * for the request and response. It takes a Ping object as the request body and returns the same - * Ping object as the response body.

- * - *

The method echoes the received Ping object, providing a simple way to test the connectivity - * or response of the service. The response contains the same information as the request, including - * the identifier (id) and content of the Ping object.

- * - * @param ping_Greeting The Ping object representing the request payload. - * @return A Ping object representing the response payload. - */ - @PostMapping(value = "/ping", produces = "application/json") - @ResponseBody - public Ping ping(@RequestBody Ping ping_Greeting) { - return ping_Greeting; - } - - /** - * Handles a POST request to retrieve information about the Dung reasoner services. This method constructs a response - * with general information about the services available, such as available semantics and commands. The input data - * includes email and other user-specific details, which are used to tailor the response. - * - * @param dungPost A {@link DungReasonerPost} object containing the data sent by the client in the POST request body. - * This typically includes identifiers like email that can be used to personalize or secure the response. - * @return A {@link DungServicesInfoResponse} object containing a variety of information about the services, - * including available semantics and commands supported by the Dung reasoner. The response is structured - * for JSON representation suitable for client-side consumption. - */ - @PostMapping(value = "/info", produces = "application/json") - @ResponseBody - public DungServicesInfoResponse getInfo(@RequestBody DungReasonerPost dungPost) { - DungServicesInfoResponse response = new DungServicesInfoResponse(); - response.setReply("info"); - response.setEmail(dungPost.getEmail()); - response.setBackend_timeout(SERVICES_TIMEOUT_DUNG); - Semantics[] sem = AbstractExtensionReasonerFactory.getSemantics(); - ArrayList semantics_ids = new ArrayList(); - for (Semantics s : sem) { - semantics_ids.add(s.abbreviation()); - } - response.setSemantics(semantics_ids); - - Command[] com = DungReasonerCalleeFactory.getCommands(); - ArrayList command_ids = new ArrayList(); - for (Command c : com) { - command_ids.add(c.id); - } - response.setCommands(command_ids); + // ── Bipolar ────────────────────────────────────────────────────────────── - // response.setSemantics(AbstractExtensionReasonerFactory.Semantics.values()); - return response; - } - - /** - * Handles HTTP POST requests for bipolar extension reasoner operations. - * - *

This method processes requests with the endpoint "/bipolar" that have the specified content types - * for both request and response. It takes a BipolarReasonerPost object as the request body and returns - * a Response object as the response body.

- * - *

The method checks the command (cmd) from the BipolarReasonerPost object and performs different - * operations based on the command. If the command is "info," it delegates the request to the getInfo - * method. If the command is "get_models" or "get_model," it processes the request using the DungTheory, - * AbstractExtensionReasoner, and other components. The result includes information about the execution - * time, answer, and status, which is encapsulated in a BipolarReasonerResponse object.

- * - *

In case of a timeout during execution, the method sets the response status to "TIMEOUT" and includes - * the specified timeout duration. If any other exception occurs, the response status is set to "Error," - * and the method provides a generic response with a time of 0.0 and a null answer.

- * - *

If the command is not recognized or not applicable, the method returns a default BipolarReasonerResponse.

- * - * @param bipolarReasonerPost The BipolarReasonerPost object representing the request payload. - * @return A Response object representing the response payload. - */ @PostMapping(value = "/bipolar", produces = "application/json", consumes = "application/json") @ResponseBody - public Response handleRequest( - @RequestBody BipolarReasonerPost bipolarReasonerPost) { - - if (bipolarReasonerPost.getCmd().equals("info")) - return (Response) getBipolarInfo(bipolarReasonerPost.getEmail()); - - if (bipolarReasonerPost.getCmd().equals("get_models") || bipolarReasonerPost.getCmd().equals("get_model") || bipolarReasonerPost.getCmd().equals("get_credulous") || bipolarReasonerPost.getCmd().equals("get_skeptical")) { - BipolarArgumentationFramework bbase = AbstractBipolarFrameworkFactory.getArgumentationFramework(bipolarReasonerPost.getNr_of_arguments(), - bipolarReasonerPost.getAttacks(), - bipolarReasonerPost.getSupports()); - BipolarSemantics semantics = BipolarSemantics.getSemantics(bipolarReasonerPost.getSemantics()); - AbstractBipolarExtensionReasoner reasoner = AbstractBipolarExtensionReasonerFactory.getReasoner(semantics); - ExecutorService executor = Executors.newSingleThreadExecutor(); - BipolarReasonerResponse reasonerResponse = new BipolarReasonerResponse( - bipolarReasonerPost.getCmd(), - bipolarReasonerPost.getEmail(), - bipolarReasonerPost.getNr_of_arguments(), - bipolarReasonerPost.getAttacks(), - bipolarReasonerPost.getSupports(), - bipolarReasonerPost.getSemantics(), - bipolarReasonerPost.getSolver(), - null, - 0, - bipolarReasonerPost.getUnit_timeout(), - "ERRORs"); - TimeUnit unit = Utils.getTimeoutUnit(bipolarReasonerPost.getUnit_timeout()); - var command = BipolarReasonerCalleeFactory.Command.getCommand(bipolarReasonerPost.getCmd()); - Callee callee = BipolarReasonerCalleeFactory.getCallee(command, reasoner, bbase); - int user_timeout = Utils.checkUserTimeout(bipolarReasonerPost.getTimeout(), SERVICES_TIMEOUT_DUNG, unit); - try { - // handle timeout - Future>> future = executor.submit(callee); - Pair>, Long> result = Utils.runServicesWithTimeout(future, - user_timeout, unit); - executor.shutdownNow(); - reasonerResponse.setTime(result.getValue()); - reasonerResponse.setAnswer(result.getKey().toString()); - reasonerResponse.setStatus("SUCCESS"); - } catch (TimeoutException e) { - reasonerResponse.setTime(bipolarReasonerPost.getTimeout()); - reasonerResponse.setAnswer(null); - reasonerResponse.setStatus("TIMEOUT"); - executor.shutdownNow(); - } catch (Exception e) { - reasonerResponse.setTime(0.0); - reasonerResponse.setAnswer(null); - reasonerResponse.setStatus("Error"); + public Response handleRequest(@RequestBody BipolarReasonerPost post) { + if (post.getCmd().equals("info")) + return getBipolarInfo(post.getEmail()); - executor.shutdownNow(); - } - return reasonerResponse; - } else { + BipolarReasonerCalleeFactory.Command cmd = BipolarReasonerCalleeFactory.Command.getCommand(post.getCmd()); + if (cmd == null) return new BipolarReasonerResponse(); - } + + BipolarArgumentationFramework bbase = AbstractBipolarFrameworkFactory.getArgumentationFramework( + post.getNr_of_arguments(), post.getAttacks(), post.getSupports()); + AbstractBipolarExtensionReasoner reasoner = AbstractBipolarExtensionReasonerFactory.getReasoner( + BipolarSemantics.getSemantics(post.getSemantics())); + Callee callee = BipolarReasonerCalleeFactory.getCallee(cmd, reasoner, bbase); + TimeUnit unit = Utils.getTimeoutUnit(post.getUnit_timeout()); + int userTimeout = Utils.checkUserTimeout(post.getTimeout(), SERVICES_TIMEOUT_DUNG, unit); + + BipolarReasonerResponse response = new BipolarReasonerResponse(post.getCmd(), post.getEmail(), + post.getNr_of_arguments(), post.getAttacks(), post.getSupports(), post.getSemantics(), + post.getSolver(), null, 0, post.getUnit_timeout(), "ERROR"); + ExecutionResult r = runCallee(callee, userTimeout, post.getTimeout(), unit); + response.setAnswer(r.answer); + response.setTime(r.time); + response.setStatus(r.status); + return response; } private BipolarServicesInfoResponse getBipolarInfo(String email) { @@ -809,172 +469,79 @@ private BipolarServicesInfoResponse getBipolarInfo(String email) { response.setReply("info"); response.setEmail(email); response.setBackend_timeout(SERVICES_TIMEOUT_DUNG); - var sem = AbstractBipolarExtensionReasonerFactory.getSemantics(); - ArrayList semantics_ids = new ArrayList(); - for (var s : sem) { + ArrayList semantics_ids = new ArrayList<>(); + for (var s : AbstractBipolarExtensionReasonerFactory.getSemantics()) semantics_ids.add(s.id); - } response.setSemantics(semantics_ids); - - BipolarReasonerCalleeFactory.Command[] com = BipolarReasonerCalleeFactory.getCommands(); - ArrayList command_ids = new ArrayList(); - for (var c : com) { + ArrayList command_ids = new ArrayList<>(); + for (var c : BipolarReasonerCalleeFactory.getCommands()) command_ids.add(c.id); - } response.setCommands(command_ids); - return response; } + // ── DeLP ───────────────────────────────────────────────────────────────── - /** - * Handles HTTP POST requests for Defeasible logic programming DeLP Reasoner operations. - * - * This method processes requests with the endpoint "/delp" that have the specified content types - * for both request and response. It takes a DeLPPost object as the request body and returns a - * DelpResponse object as the response body. - * - * The method prints the received DelpPost object to the console for debugging purposes. It then - * constructs a DeLPResponse object with default values, prepares the DelpReasoner, and executes it - * asynchronously using a separate thread. The result includes information about the execution time, - * answer, and status, encapsulated in a DelpResponse object. - * - * If the execution times out, the method sets the response status to "TIMEOUT" and includes the - * specified timeout duration. If a parsing exception occurs during knowledge base or query parsing, - * the method throws a JSONException with an appropriate error message. If any other unexpected exception - * occurs, the method prints the stack trace and throws a JSONException with a generic error message. - * - * @param delpPost The DelpPost object representing the request payload. - * @return A Response object representing the response payload. - * @throws JSONException If there is a parsing error or an unexpected error occurs during processing. - */ @PostMapping(value = "/delp", produces = "application/json", consumes = "application/json") @ResponseBody - public Response handleRequest( - @RequestBody DeLPPost delpPost) { - - System.out.println(delpPost.toString()); - - DeLPResponse delpResponse = new DeLPResponse("query", delpPost.getEmail(), delpPost.getCompcriterion(), - delpPost.getKb(), delpPost.getQuery(), delpPost.getTimeout(), null, 0.0, delpPost.getUnit_timeout(), - null); - TimeUnit unit = Utils.getTimeoutUnit(delpPost.getUnit_timeout()); - int user_timeout = Utils.checkUserTimeout(delpPost.getTimeout(), SERVICES_TIMEOUT_DELP, unit); + public Response handleRequest(@RequestBody DeLPPost post) { + DeLPResponse response = new DeLPResponse("query", post.getEmail(), post.getCompcriterion(), + post.getKb(), post.getQuery(), post.getTimeout(), null, 0.0, post.getUnit_timeout(), null); + TimeUnit unit = Utils.getTimeoutUnit(post.getUnit_timeout()); + int userTimeout = Utils.checkUserTimeout(post.getTimeout(), SERVICES_TIMEOUT_DELP, unit); ExecutorService executor = Executors.newSingleThreadExecutor(); try { - DelpParser parser = new DelpParser(); - DefeasibleLogicProgram delp = parser.parseBeliefBase(delpPost.getKb()); + DefeasibleLogicProgram delp = parser.parseBeliefBase(post.getKb()); ComparisonCriterion comp = null; - if (delpPost.getCompcriterion().equals("compcriterion")) + if (post.getCompcriterion().equals("compcriterion")) comp = new EmptyCriterion(); - if (delpPost.getCompcriterion().equals("genspec")) + if (post.getCompcriterion().equals("genspec")) comp = new GeneralizedSpecificity(); if (comp == null) throw new JSONException("Malformed JSON: unknown value for attribute \"compcriterion\""); DelpReasoner reasoner = new DelpReasoner(comp); FolParser folParser = new FolParser(); folParser.setSignature(parser.getSignature()); - String qString = delpPost.getQuery().trim(); - Formula f = null; - if (qString.startsWith("~")) - f = new Negation((FolFormula) folParser.parseFormula(qString.substring(1))); - else - f = folParser.parseFormula(qString); - Callee delpCallee = new DeLPCallee(delp, reasoner, f); - Future future = executor.submit(delpCallee); - Pair result = Utils.runServicesWithTimeout(future, user_timeout, unit); - - System.out.println(result.toString()); - - delpResponse.setAnswer(result.getKey().toString()); - delpResponse.setTime(result.getValue()); - delpResponse.setStatus("SUCCESS"); - System.out.println(delpResponse.toString()); - + String qString = post.getQuery().trim(); + Formula f = qString.startsWith("~") + ? new Negation((FolFormula) folParser.parseFormula(qString.substring(1))) + : folParser.parseFormula(qString); + Future future = executor.submit(new DeLPCallee(delp, reasoner, f)); + Pair result = Utils.runServicesWithTimeout(future, userTimeout, unit); + response.setAnswer(result.getKey().toString()); + response.setTime(result.getValue()); + response.setStatus("SUCCESS"); } catch (TimeoutException e) { - delpResponse.setTime(delpPost.getTimeout()); - delpResponse.setAnswer(null); - delpResponse.setStatus("TIMEOUT"); - executor.shutdownNow(); - } catch (ParserException e) { - executor.shutdownNow(); - throw new JSONException( - "Malformed JSON: syntax of knowledge base and/or query does not conform to the given format."); - } catch (IOException e) { - executor.shutdownNow(); - throw new JSONException( - "Malformed JSON: syntax of knowledge base and/or query does not conform to the given format."); + response.setTime(post.getTimeout()); + response.setAnswer(null); + response.setStatus("TIMEOUT"); + } catch (ParserException | IOException e) { + throw new JSONException("Malformed JSON: syntax of knowledge base and/or query does not conform to the given format."); } catch (Exception e) { - executor.shutdownNow(); - e.printStackTrace(); throw new JSONException("An unexpected error occured. Please contact an administrator."); + } finally { + executor.shutdownNow(); } - return delpResponse; + return response; } - /** - * Handles HTTP POST requests for Inconsistency Measures operations. - * - * This method processes requests with the endpoint "/incmes" that have the specified content type - * for the request and response. It takes an InconsistencyPost object as the request body and returns a - * Response object as the response body. - * - * The method initializes an InconsistencyValueResponse object for the response. It then checks the - * command (cmd) from the InconsistencyPost object and delegates the request to specific methods based on - * the command. If the command is "value," it calls the handleGetICMESValue method. If the command is - * "measures," it calls the handleGetMeasures method. Any exceptions that occur during the processing are - * caught, and a generic error message is printed to the console. - * - * If the command is not recognized or not applicable, the method returns a default InconsistencyValueResponse. - * - * @param incmesPost The InconsistencyPost object representing the request payload. - * @return A Response object representing the response payload. - */ + // ── Inconsistency Measures ──────────────────────────────────────────────── @PostMapping(value = "/incmes", produces = "application/json") @ResponseBody - public Response handleRequest( - @RequestBody InconsistencyPost incmesPost) { - InconsistencyValueResponse icmesResponse = new InconsistencyValueResponse(); - + public Response handleRequest(@RequestBody InconsistencyPost post) { try { - - if (incmesPost.getCmd().equals("value")) { - return handleGetICMESValue(incmesPost); - } - - if (incmesPost.getCmd().equals("measures")) { - - return handleGetMeasures(incmesPost); - } + if (post.getCmd().equals("value")) + return handleGetICMESValue(post); + if (post.getCmd().equals("measures")) + return handleGetMeasures(post); } catch (Exception e) { - System.out.println(e.getMessage()); + LoggerUtil.logger.log(Level.SEVERE, e.getMessage()); } - - return icmesResponse; + return new InconsistencyValueResponse(); } - /** - * Private inner class representing a Callable task for measuring inconsistency of a belief set. - * - * The MeasurementCallee class implements the Callable interface with a generic type of Double. - * Instances of this class are used to perform asynchronous calculations of inconsistency measures - * for a given BeliefSet using a specific InconsistencyMeasure. - * - * The class has two fields: "measure," representing the InconsistencyMeasure to be applied, - * and "beliefSet," representing the BeliefSet for which the inconsistency measure is calculated. - * - * The constructor initializes the MeasurementCallee with a specific InconsistencyMeasure and - * a BeliefSet. - * - * The call method, required by the Callable interface, invokes the inconsistencyMeasure method - * of the provided InconsistencyMeasure on the given BeliefSet, returning the calculated inconsistency - * measure value as a Double. - * - * @param The type of formulas in the belief set, e.g., PlFormula. - * @param The type of signature associated with the belief set, e.g., PlSignature. - */ private class MeasurementCallee implements Callable { InconsistencyMeasure> measure; BeliefSet beliefSet; @@ -991,112 +558,64 @@ public Double call() throws Exception { } } - /** - * - * Handles the computation of the inconsistency value for a given belief set and inconsistency measure. - * This method takes an InconsistencyPost object representing the request payload and calculates - * the inconsistency value based on the specified belief set, inconsistency measure, and other parameters. - * - * The method initializes an InconsistencyValueResponse object for the response and sets up the necessary - * sub-solvers for the computation. It then retrieves the inconsistency measure and parser based on the request's - * attributes. The belief set is parsed from the knowledge base using the selected parser, and an asynchronous - * calculation of the inconsistency measure is performed using a separate thread. The execution time and result - * are then encapsulated in the InconsistencyValueResponse object. - * - * If the calculation times out, the method sets the response status to "TIMEOUT" and includes the specified - * timeout duration. If a parsing exception occurs during knowledge base parsing, the method throws a JSONException - * with an appropriate error message. If any other unexpected exception occurs, the method logs the error and - * throws a JSONException with a generic error message. - * - * The inconsistency value is set to specific sentinel values (-1 for timeout, -2 for general error, -3 for infinity), - * and the response object includes information about the request and the computed inconsistency value. - * - * @param query The InconsistencyPost object representing the request payload. - * @return An InconsistencyValueResponse object representing the response payload. - * @throws JSONException If there is a parsing error or an unexpected error occurs during processing. - */ - private InconsistencyValueResponse handleGetICMESValue(InconsistencyPost query) throws JSONException { - InconsistencyValueResponse icmesResponse = new InconsistencyValueResponse(); + InconsistencyValueResponse response = new InconsistencyValueResponse(); TimeUnit unit = Utils.getTimeoutUnit(query.getUnit_timeout()); - int user_timeout = Utils.checkUserTimeout(query.getTimeout(), SERVICES_TIMEOUT_INCMES, unit); - // set sub-solvers + int userTimeout = Utils.checkUserTimeout(query.getTimeout(), SERVICES_TIMEOUT_INCMES, unit); SatSolver.setDefaultSolver(new Sat4jSolver()); PlMusEnumerator.setDefaultEnumerator(new NaiveMusEnumerator(new Sat4jSolver())); Solver.setDefaultLinearSolver(new ApacheCommonsSimplex()); Solver.setDefaultIntegerLinearSolver(new GlpkSolver()); - // get measure InconsistencyMeasure> measure = InconsistencyMeasureFactory.getInconsistencyMeasure( Measure.getMeasure(query.getMeasure())); if (measure == null) throw new JSONException("Malformed JSON: unknown value for attribute \"measure\""); - Parser parser = PlParserFactory.getParserForFormat( - Format.getFormat(query.getFormat())); + Parser parser = PlParserFactory.getParserForFormat(Format.getFormat(query.getFormat())); if (parser == null) throw new JSONException("Malformed JSON: unknown value for attribute \"format\""); double val = -3; try { PlBeliefSet beliefSet = parser.parseBeliefBase(query.getKb()); ExecutorService executor = Executors.newSingleThreadExecutor(); - long millis = System.currentTimeMillis(); try { - // handle timeout Future future = executor.submit(new MeasurementCallee(measure, beliefSet)); - Pair result = Utils.runServicesWithTimeout(future, user_timeout, unit); + Pair result = Utils.runServicesWithTimeout(future, userTimeout, unit); val = result.getKey(); - icmesResponse.setTime(result.getValue()); - icmesResponse.setStatus("SUCCESS"); - // val = future.get(InconsistencyMeasurementService.timeout, TimeUnit.SECONDS); + response.setTime(result.getValue()); + response.setStatus("SUCCESS"); executor.shutdownNow(); } catch (TimeoutException e) { - // inconsistency value of -1 indicates that a timeout has occurred - icmesResponse.setTime(query.getTimeout()); - icmesResponse.setStatus("TIMEOUT"); + response.setTime(query.getTimeout()); + response.setStatus("TIMEOUT"); executor.shutdownNow(); val = -1; } catch (Exception e) { - // inconsistency value of -2 indicates some general error - icmesResponse.setStatus("ERROR"); + response.setStatus("ERROR"); executor.shutdownNow(); val = -2; } - // inconsistency value of -3 indicates infinity if (val == Double.POSITIVE_INFINITY) val = -3; - millis = System.currentTimeMillis() - millis; - - icmesResponse.setEmail(query.getEmail()); - icmesResponse.setFormat(query.getFormat()); - icmesResponse.setKb(query.getKb()); - icmesResponse.setMeasure(query.getMeasure()); - icmesResponse.setReply("value"); - icmesResponse.setValue(val); - - return icmesResponse; - } catch (ParserException e) { - throw new JSONException("Malformed JSON: syntax of knowledge base does not conform to the given format."); - } catch (IOException e) { + response.setEmail(query.getEmail()); + response.setFormat(query.getFormat()); + response.setKb(query.getKb()); + response.setMeasure(query.getMeasure()); + response.setReply("value"); + response.setValue(val); + return response; + } catch (ParserException | IOException e) { throw new JSONException("Malformed JSON: syntax of knowledge base does not conform to the given format."); } catch (Exception e) { throw new JSONException("An unexpected error occured. Please contact an administrator."); } } - /** - * Handles the "List inconsistency measures" command - * - * @param query some query - * @return the reply - * @throws JSONException if some JSON issue occurs. - * @throws org.codehaus.jettison.json.JSONException if some JSON issue occurs. - */ private InconsistencyGetMeasuresResponse handleGetMeasures(InconsistencyPost query) throws JSONException, org.codehaus.jettison.json.JSONException { InconsistencyGetMeasuresResponse response = new InconsistencyGetMeasuresResponse(); - List> value = new LinkedList>(); - HashMap jsonMes; + List> value = new LinkedList<>(); for (Measure m : InconsistencyMeasureFactory.Measure.values()) { - jsonMes = new HashMap(); + HashMap jsonMes = new HashMap<>(); jsonMes.put("id", m.id); jsonMes.put("label", m.label); value.add(jsonMes); @@ -1107,24 +626,13 @@ private InconsistencyGetMeasuresResponse handleGetMeasures(InconsistencyPost que return response; } - - /** - * Handles the "List semanctics" command for aba - * - * @param query some query - * @return the reply - * @throws JSONException if some JSON issue occurs. - * @throws org.codehaus.jettison.json.JSONException if some JSON issue occurs. - */ private AbaGetSemanticsResponse handleGetSemantics(AbaReasonerPost query) throws JSONException, org.codehaus.jettison.json.JSONException { - LoggerUtil.logger.info(String.format("User: %s Command: %s", query.getEmail(), query.getCmd())); AbaGetSemanticsResponse response = new AbaGetSemanticsResponse(); - List> value = new LinkedList>(); - HashMap jsonMes; - for (org.tweetyproject.web.services.aba.GeneralAbaReasonerFactory.Semantics m : GeneralAbaReasonerFactory.Semantics.values()) { - jsonMes = new HashMap(); + List> value = new LinkedList<>(); + for (GeneralAbaReasonerFactory.Semantics m : GeneralAbaReasonerFactory.Semantics.values()) { + HashMap jsonMes = new HashMap<>(); jsonMes.put("id", m.id); jsonMes.put("label", m.label); value.add(jsonMes); @@ -1135,307 +643,93 @@ private AbaGetSemanticsResponse handleGetSemantics(AbaReasonerPost query) return response; } - /** - * handler for the /sequence-explanation endpoint - * @param request the sequence explanation request - * @return the server response - */ + // ── Sequence Explanation ────────────────────────────────────────────────── + @PostMapping(value = "/sequence-explanation", produces = "application/json") @ResponseBody public SequenceExplanationResponse handleRequest(@Valid @RequestBody SequenceExplanationPost request) { LoggerUtil.logger.info(String.format("Run sequence explanation command \"%s\" for user \"%s\" with timeout: %s %s", - request.getCmd().getClass().getSimpleName(), - request.getEmail(), - request.getTimeout(), - request.getUnit_timeout())); + request.getCmd().getClass().getSimpleName(), request.getEmail(), + request.getTimeout(), request.getUnit_timeout())); TimeUnit timeoutUnit = Utils.getTimeoutUnit(request.getUnit_timeout()); int timeout = Utils.checkUserTimeout(request.getTimeout(), SERVICES_TIMEOUT_SEQUENCE_EXPLANATION, timeoutUnit); - ExecutorService executor = Executors.newSingleThreadExecutor(); - Pair resultAndExecutionTime; + Pair resultAndTime; try { var future = executor.submit(() -> processCommand(request.getCmd())); - resultAndExecutionTime = Utils.runServicesWithTimeout(future, timeout, timeoutUnit); + resultAndTime = Utils.runServicesWithTimeout(future, timeout, timeoutUnit); } catch (TimeoutException e) { LoggerUtil.logger.info("Timeout while running sequence explanation."); - return new SequenceExplanationResponse( - null, - request.getEmail(), - timeout, - request.getUnit_timeout(), - SequenceExplanationResponse.Status.TIMEOUT - ); + return new SequenceExplanationResponse(null, request.getEmail(), timeout, + request.getUnit_timeout(), SequenceExplanationResponse.Status.TIMEOUT); } catch (ExecutionException e) { LoggerUtil.logger.warning(() -> "Error while running sequence explanation reasoner: " + e.getMessage()); e.printStackTrace(); throw new RuntimeException(e); } catch (InterruptedException e) { - LoggerUtil.logger.warning(() -> "Interrupt while running sequence explanation: " + e.getMessage()); + LoggerUtil.logger.warning(() -> "Interrupt while running sequence explanation: " + e.getMessage()); e.printStackTrace(); Thread.currentThread().interrupt(); throw new RuntimeException("Thread was interrupted."); } finally { executor.shutdownNow(); } - - double executionTime = resultAndExecutionTime.getValue(); - var result = resultAndExecutionTime.getKey(); - return new SequenceExplanationResponse( - result, - request.getEmail(), - executionTime, - request.getUnit_timeout(), - SequenceExplanationResponse.Status.SUCCESS - ); + return new SequenceExplanationResponse(resultAndTime.getKey(), request.getEmail(), + resultAndTime.getValue(), request.getUnit_timeout(), SequenceExplanationResponse.Status.SUCCESS); } private SequenceExplanationResult processCommand(SequenceExplanationCmd cmd) { - if (cmd instanceof GetSequenceExplanationsCmd) { + if (cmd instanceof GetSequenceExplanationsCmd) return processSequenceExplanationCmd((GetSequenceExplanationsCmd) cmd); - } else { - throw new IllegalStateException("Encountered invalid command:" + cmd.getClass().getSimpleName()); - } + throw new IllegalStateException("Encountered invalid command:" + cmd.getClass().getSimpleName()); } private GetSequenceExplanationsResult processSequenceExplanationCmd(GetSequenceExplanationsCmd cmd) { var theory = new DungTheory(); - for (AttackDTO attackDTO: cmd.getAttacks()) { + for (AttackDTO attackDTO : cmd.getAttacks()) { var attacker = new Argument(attackDTO.getAttacker()); var attacked = new Argument(attackDTO.getAttacked()); theory.add(attacker); theory.add(attacked); - var attack = new Attack(attacker, attacked); - theory.add(attack); + theory.add(new Attack(attacker, attacked)); } Set argumentFilter = ArgumentFilterSerialization.deserialize(cmd.getArgumentFilter()); - if (argumentFilter != null) { + if (argumentFilter != null) theory.addAll(argumentFilter); - } - var sequenceExplanation = sequenceExplanationService.querySequenceExplanations(theory, argumentFilter); - return GetSequenceExplanationsResult.from(sequenceExplanation); - } - - /** - * Executes the causal reasoner as specified by the provided {@link CausalReasonerPost} - * - * @param request The request payload containing information for causal reasoning - * @return A Response object containing the result of the ABA reasoning operation. - */ - @PostMapping(value = "/causal", produces = "application/json") - @ResponseBody - public CausalReasonerResponse handleRequest(@Valid @RequestBody CausalReasonerPost request) { - LoggerUtil.logger.info(String.format("Run causal reasoner command \"%s\" for user \"%s\" with timeout: %s %s", - request.getCmd(), - request.getEmail(), - request.getTimeout(), - request.getUnit_timeout())); - - TimeUnit timoutUnit = Utils.getTimeoutUnit(request.getUnit_timeout()); - int timout = Utils.checkUserTimeout(request.getTimeout(), SERVICES_TIMEOUT_CAUSAL, timoutUnit); - - ExecutorService executor = Executors.newSingleThreadExecutor(); - Pair resultAndExecutionTime; - try { - var future = executor.submit(() -> processCommand(request)); - resultAndExecutionTime = Utils.runServicesWithTimeout(future, timout, timoutUnit); - } catch (TimeoutException e) { - LoggerUtil.logger.info("Timeout while running causal reasoner."); - return new CausalReasonerResponse( - null, - request.getEmail(), - timout, - request.getUnit_timeout(), - TIMEOUT - ); - } catch (ExecutionException e) { - LoggerUtil.logger.warning(() -> "Error while running causal reasoner: " + e.getMessage()); - e.printStackTrace(); - throw new RuntimeException(e); - } catch (InterruptedException e) { - LoggerUtil.logger.warning(() -> "Interrupt while running causal reasoner: " + e.getMessage()); - e.printStackTrace(); - Thread.currentThread().interrupt(); - throw new RuntimeException("Thread was interrupted."); - } finally { - executor.shutdownNow(); - } - - double executionTime = resultAndExecutionTime.getValue(); - String result = resultAndExecutionTime.getKey(); - return new CausalReasonerResponse( - result, - request.getEmail(), - executionTime, - request.getUnit_timeout(), - SUCCESS - ); - } - - private String processCommand(CausalReasonerPost causalReasonerPost) { - return switch (causalReasonerPost.getCmd()) { - case GET_CONCLUSIONS -> processConclusionsCommand(causalReasonerPost); - case GET_SIGNIFICANT_ATOMS -> processSignificantAtomsCommand(causalReasonerPost); - case GET_ARGUMENTATION_FRAMEWORK -> processArgumentationFramework(causalReasonerPost); - case GET_SEQUENCE_EXPLANATIONS -> processSequenceExplanations(causalReasonerPost); - }; - } - - private String processConclusionsCommand(CausalReasonerPost causalReasonerPost) { - CausalKnowledgeBase causalKnowledgeBase = parseCausalKnowledgeBase(causalReasonerPost); - Collection observations = parseObservations(causalReasonerPost); - var conclusionFilter = parseConclusionFilter(causalReasonerPost); - - Collection conclusions = causalReasonerService.queryConclusions(causalKnowledgeBase, observations, conclusionFilter); - return conclusions.toString(); - } - - private String processSignificantAtomsCommand(CausalReasonerPost causalReasonerPost) { - CausalKnowledgeBase causalKnowledgeBase = parseCausalKnowledgeBase(causalReasonerPost); - Collection observations = parseObservations(causalReasonerPost); - var conclusionFilter = parseConclusionFilter(causalReasonerPost); - - var perAtomSignificantAtoms = causalReasonerService.queryPerAtomSignificantAtoms(causalKnowledgeBase, observations, conclusionFilter); - - Map> jsonData = new HashMap<>(); - for (Map.Entry> entry : perAtomSignificantAtoms.entrySet()) { - List list = new ArrayList<>(); - for (Proposition proposition : entry.getValue()) { - String string = proposition.toString(); - list.add(string); - } - jsonData.put(entry.getKey().toString(), list); - } - - try { - return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonData); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - } - - private String processSequenceExplanations(CausalReasonerPost causalReasonerPost) { - CausalKnowledgeBase causalKnowledgeBase = parseCausalKnowledgeBase(causalReasonerPost); - Collection observations = parseObservations(causalReasonerPost); - var conclusionFilter = parseConclusionFilter(causalReasonerPost); - - var result = causalReasonerService.querySequenceExplanations(causalKnowledgeBase, observations, conclusionFilter); - var reply = SequenceExplanationReply.from(result); - try { - return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(reply); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - } - - private String processArgumentationFramework(CausalReasonerPost causalReasonerPost) { - CausalKnowledgeBase causalKnowledgeBase = parseCausalKnowledgeBase(causalReasonerPost); - Collection observations = parseObservations(causalReasonerPost); - - var result = causalReasonerService.queryArgumentationFramework(causalKnowledgeBase, observations); - var reply = ArgumentationFrameworkReply.from(result); - try { - return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(reply); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - } - - private static Collection parseObservations(CausalReasonerPost causalReasonerPost) { - CausalParser causalParser = new CausalParser(); - Collection observations; - try { - observations = causalParser.parseListOfFormulae(causalReasonerPost.getObservations(), ","); - } catch (ParserException e) { - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, null, e); - } catch (IOException e) { - throw new RuntimeException(e); - } - return observations; + return GetSequenceExplanationsResult.from(sequenceExplanationService.querySequenceExplanations(theory, argumentFilter)); } - private static @Nullable Set parseConclusionFilter(CausalReasonerPost causalReasonerPost) { - return ConclusionsFilterSerialization.parse(causalReasonerPost.getConclusionsFilter()); - } - - private static CausalKnowledgeBase parseCausalKnowledgeBase(CausalReasonerPost causalReasonerPost) { - CausalParser causalParser = new CausalParser(); - CausalKnowledgeBase causalKnowledgeBase; - try { - causalKnowledgeBase = causalParser.parseBeliefBase(causalReasonerPost.getKb()); - } catch (ParserException e) { - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, null, e); - } catch (IOException e) { - throw new RuntimeException(e); - } - return causalKnowledgeBase; - } + // ── PAF ────────────────────────────────────────────────────────────────── - /** - * Handles HTTP POST requests for Probabilistic Argumentation Framework (PAF) operations. - * - *

Supported commands: - *

    - *
  • {@code info} – return supported semantics, commands, and solvers
  • - *
  • {@code get_credulous} – probability that the queried argument is credulously accepted
  • - *
  • {@code get_skeptical} – probability that the queried argument is skeptically accepted
  • - *
- * - *

Two solvers are available: {@code simple} (exact, enumerates all subgraphs) and - * {@code montecarlo} (approximate sampling, configurable via {@code nr_of_trials}).

- * - * @param pafPost the request payload - * @return a {@link Response} containing the computed probability or service info - */ @PostMapping(value = "/paf", produces = "application/json", consumes = "application/json") @ResponseBody - public Response handleRequest(@RequestBody PafReasonerPost pafPost) { - if (pafPost.getCmd().equals("info")) - return getPafInfo(pafPost.getEmail()); + public Response handleRequest(@RequestBody PafReasonerPost post) { + if (post.getCmd().equals("info")) + return getPafInfo(post.getEmail()); - PafReasonerCalleeFactory.Command cmd = PafReasonerCalleeFactory.Command.getCommand(pafPost.getCmd()); + PafReasonerCalleeFactory.Command cmd = PafReasonerCalleeFactory.Command.getCommand(post.getCmd()); if (cmd == null) return new PafReasonerResponse(); ProbabilisticArgumentationFramework paf = AbstractPafReasonerFactory.getPaf( - pafPost.getNr_of_arguments(), - pafPost.getArgument_probabilities(), - pafPost.getAttacks(), - pafPost.getAttack_probabilities()); + post.getNr_of_arguments(), post.getArgument_probabilities(), + post.getAttacks(), post.getAttack_probabilities()); AbstractPafReasoner reasoner = AbstractPafReasonerFactory.getReasoner( - Semantics.getSemantics(pafPost.getSemantics()), - pafPost.getSolver(), - pafPost.getNr_of_trials()); + Semantics.getSemantics(post.getSemantics()), post.getSolver(), post.getNr_of_trials()); Callee callee = PafReasonerCalleeFactory.getCallee(cmd, reasoner, paf); - - ExecutorService executor = Executors.newSingleThreadExecutor(); - PafReasonerResponse reasonerResponse = new PafReasonerResponse( - pafPost.getCmd(), pafPost.getEmail(), pafPost.getNr_of_arguments(), - pafPost.getArgument_probabilities(), pafPost.getAttacks(), - pafPost.getAttack_probabilities(), pafPost.getSemantics(), - pafPost.getSolver(), pafPost.getArgument(), null, 0, - pafPost.getUnit_timeout(), "ERROR"); - TimeUnit unit = Utils.getTimeoutUnit(pafPost.getUnit_timeout()); - int user_timeout = Utils.checkUserTimeout(pafPost.getTimeout(), SERVICES_TIMEOUT_DUNG, unit); - try { - Future> future = executor.submit(callee); - Pair, Long> result = Utils.runServicesWithTimeout(future, user_timeout, unit); - executor.shutdownNow(); - reasonerResponse.setAnswer(result.getKey().toString()); - reasonerResponse.setTime(result.getValue()); - reasonerResponse.setStatus("SUCCESS"); - } catch (TimeoutException e) { - reasonerResponse.setTime(pafPost.getTimeout()); - reasonerResponse.setAnswer(null); - reasonerResponse.setStatus("TIMEOUT"); - executor.shutdownNow(); - } catch (Exception e) { - reasonerResponse.setTime(0.0); - reasonerResponse.setAnswer(null); - reasonerResponse.setStatus("Error"); - executor.shutdownNow(); - } - return reasonerResponse; + TimeUnit unit = Utils.getTimeoutUnit(post.getUnit_timeout()); + int userTimeout = Utils.checkUserTimeout(post.getTimeout(), SERVICES_TIMEOUT_DUNG, unit); + + PafReasonerResponse response = new PafReasonerResponse(post.getCmd(), post.getEmail(), + post.getNr_of_arguments(), post.getArgument_probabilities(), post.getAttacks(), + post.getAttack_probabilities(), post.getSemantics(), post.getSolver(), + post.getArgument(), null, 0, post.getUnit_timeout(), "ERROR"); + ExecutionResult r = runCallee(callee, userTimeout, post.getTimeout(), unit); + response.setAnswer(r.answer); + response.setTime(r.time); + response.setStatus(r.status); + return response; } private PafServicesInfoResponse getPafInfo(String email) { @@ -1443,102 +737,47 @@ private PafServicesInfoResponse getPafInfo(String email) { response.setReply("info"); response.setEmail(email); response.setBackend_timeout(SERVICES_TIMEOUT_DUNG); - Semantics[] sem = AbstractPafReasonerFactory.getSemantics(); ArrayList semantics_ids = new ArrayList<>(); - for (Semantics s : sem) + for (Semantics s : AbstractPafReasonerFactory.getSemantics()) semantics_ids.add(s.abbreviation()); response.setSemantics(semantics_ids); - PafReasonerCalleeFactory.Command[] com = PafReasonerCalleeFactory.getCommands(); ArrayList command_ids = new ArrayList<>(); - for (PafReasonerCalleeFactory.Command c : com) + for (PafReasonerCalleeFactory.Command c : PafReasonerCalleeFactory.getCommands()) command_ids.add(c.id); response.setCommands(command_ids); response.setSolvers(AbstractPafReasonerFactory.getSolvers()); return response; } - /** - * Handles HTTP POST requests for Serialisation operations. - * - *

Supported commands: - *

    - *
  • {@code info} – return supported commands and functions
  • - *
  • {@code get_reduct} – compute the reduct for the given AF and extension
  • - *
  • {@code get_selection} – get the selectable initial sets for the given AF and selection function
  • - *
  • {@code is_terminal} – determine whether the given AF and extension are a terminal state according to the termination function
  • - *
- * - * @param serPost the request payload - * @return a {@link Response} containing the computed result or service info - */ + // ── Serialisation ───────────────────────────────────────────────────────── + @PostMapping(value = "/serialisation", produces = "application/json", consumes = "application/json") @ResponseBody - public Response handleRequest(@RequestBody SerialisationPost serPost) { - if (serPost.getCmd().equals("info")) - return getSerInfo(serPost.getEmail()); + public Response handleRequest(@RequestBody SerialisationPost post) { + if (post.getCmd().equals("info")) + return getSerInfo(post.getEmail()); - SerialisationCalleeFactory.Command cmd = SerialisationCalleeFactory.Command.getCommand(serPost.getCmd()); + SerialisationCalleeFactory.Command cmd = SerialisationCalleeFactory.Command.getCommand(post.getCmd()); if (cmd == null) return new SerialisationResponse(); - DungTheory theory = AbstractExtensionReasonerFactory.getDungTheory( - serPost.getNr_of_arguments(), - serPost.getAttacks()); - Extension extension = SerialisationFactory.getExtension(serPost.getExtension()); - SelectionFunction alpha = SerialisationFactory.getSelectionFunction(serPost.getSelectionFunction()); - TerminationFunction beta = SerialisationFactory.getTerminationFunction(serPost.getTerminationFunction()); + DungTheory theory = AbstractExtensionReasonerFactory.getDungTheory(post.getNr_of_arguments(), post.getAttacks()); + Extension extension = SerialisationFactory.getExtension(post.getExtension()); + SelectionFunction alpha = SerialisationFactory.getSelectionFunction(post.getSelectionFunction()); + TerminationFunction beta = SerialisationFactory.getTerminationFunction(post.getTerminationFunction()); Callee callee = SerialisationCalleeFactory.getCallee(cmd, alpha, beta, theory, extension); - - ExecutorService executor = Executors.newSingleThreadExecutor(); - SerialisationResponse reasonerResponse = new SerialisationResponse( - serPost.getCmd(), serPost.getEmail(), serPost.getNr_of_arguments(), serPost.getAttacks(), - serPost.getExtension(), serPost.getSelectionFunction(), - serPost.getTerminationFunction(), null, 0, - serPost.getUnit_timeout(), "ERROR"); - TimeUnit unit = Utils.getTimeoutUnit(serPost.getUnit_timeout()); - int user_timeout = Utils.checkUserTimeout(serPost.getTimeout(), SERVICES_TIMEOUT_DUNG, unit); - try { - String result_str; - Long result_time; - switch (cmd) { - case GET_SEQUENCES -> { - Future> future = executor.submit(callee); - Pair, Long> result = Utils.runServicesWithTimeout(future, user_timeout, unit); - result_str = result.getKey().toString(); - result_time = result.getValue(); - } case GET_REDUCT -> { - Future future = executor.submit(callee); - Pair result = Utils.runServicesWithTimeout(future, user_timeout, unit); - result_str = result.getKey().toString(); - result_time = result.getValue(); - } case IS_TERMINAL -> { - Future future = executor.submit(callee); - Pair result = Utils.runServicesWithTimeout(future, user_timeout, unit); - result_str = result.getKey().toString(); - result_time = result.getValue(); - } case GET_SELECTION,GET_MODELS -> { - Future>> future = executor.submit(callee); - Pair>, Long> result = Utils.runServicesWithTimeout(future, user_timeout, unit); - result_str = result.getKey().toString(); - result_time = result.getValue(); - } default -> throw new IllegalArgumentException("unknown command " + cmd); - } - executor.shutdownNow(); - reasonerResponse.setAnswer(result_str); - reasonerResponse.setTime(result_time); - reasonerResponse.setStatus("SUCCESS"); - } catch (TimeoutException e) { - reasonerResponse.setTime(serPost.getTimeout()); - reasonerResponse.setAnswer(null); - reasonerResponse.setStatus("TIMEOUT"); - executor.shutdownNow(); - } catch (Exception e) { - reasonerResponse.setTime(0.0); - reasonerResponse.setAnswer(null); - reasonerResponse.setStatus("Error"); - executor.shutdownNow(); - } - return reasonerResponse; + TimeUnit unit = Utils.getTimeoutUnit(post.getUnit_timeout()); + int userTimeout = Utils.checkUserTimeout(post.getTimeout(), SERVICES_TIMEOUT_DUNG, unit); + + SerialisationResponse response = new SerialisationResponse(post.getCmd(), post.getEmail(), + post.getNr_of_arguments(), post.getAttacks(), post.getExtension(), + post.getSelectionFunction(), post.getTerminationFunction(), null, 0, + post.getUnit_timeout(), "ERROR"); + ExecutionResult r = runCallee(callee, userTimeout, post.getTimeout(), unit); + response.setAnswer(r.answer); + response.setTime(r.time); + response.setStatus(r.status); + return response; } private SerialisationInfoResponse getSerInfo(String email) { @@ -1548,11 +787,18 @@ private SerialisationInfoResponse getSerInfo(String email) { response.setBackend_timeout(SERVICES_TIMEOUT_DUNG); response.setSelectionFunctions(SerialisationFactory.getSelectionFunctions()); response.setTerminationFunctions(SerialisationFactory.getTerminationFunction()); - SerialisationCalleeFactory.Command[] com = SerialisationCalleeFactory.getCommands(); ArrayList command_ids = new ArrayList<>(); - for (SerialisationCalleeFactory.Command c : com) + for (SerialisationCalleeFactory.Command c : SerialisationCalleeFactory.getCommands()) command_ids.add(c.id); response.setCommands(command_ids); return response; } + + // ── Ping ───────────────────────────────────────────────────────────────── + + @PostMapping(value = "/ping", produces = "application/json") + @ResponseBody + public Ping ping(@RequestBody Ping ping_Greeting) { + return ping_Greeting; + } } diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/causal/CausalController.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/causal/CausalController.java new file mode 100644 index 000000000..cf7241599 --- /dev/null +++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/causal/CausalController.java @@ -0,0 +1,186 @@ +/* + * This file is part of "TweetyProject", a collection of Java libraries for + * logical aspects of artificial intelligence and knowledge representation. + * + * TweetyProject is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Copyright 2016 The TweetyProject Team + */ +package org.tweetyproject.web.services.causal; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.lang.Nullable; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.server.ResponseStatusException; +import org.tweetyproject.causal.parser.CausalParser; +import org.tweetyproject.causal.syntax.CausalKnowledgeBase; +import org.tweetyproject.commons.ParserException; +import org.tweetyproject.logics.pl.syntax.PlFormula; +import org.tweetyproject.logics.pl.syntax.Proposition; +import org.tweetyproject.web.services.LoggerUtil; +import org.tweetyproject.web.services.Utils; + +import javafx.util.Pair; + +import javax.validation.Valid; + +import static org.tweetyproject.web.services.causal.CausalReasonerResponse.Status.SUCCESS; +import static org.tweetyproject.web.services.causal.CausalReasonerResponse.Status.TIMEOUT; + +/** + * Handles HTTP POST requests for the {@code /causal} endpoint. + */ +@RestController +public class CausalController { + + private static final int TIMEOUT_SECONDS = 300; + + private final ObjectMapper objectMapper; + private final CausalReasonerService causalReasonerService; + + @Autowired + public CausalController(ObjectMapper objectMapper, CausalReasonerService causalReasonerService) { + this.objectMapper = objectMapper; + this.causalReasonerService = causalReasonerService; + } + + @PostMapping(value = "/causal", produces = "application/json") + @ResponseBody + public CausalReasonerResponse handleRequest(@Valid @RequestBody CausalReasonerPost request) { + LoggerUtil.logger.info(String.format("Run causal reasoner command \"%s\" for user \"%s\" with timeout: %s %s", + request.getCmd(), request.getEmail(), request.getTimeout(), request.getUnit_timeout())); + + TimeUnit timeoutUnit = Utils.getTimeoutUnit(request.getUnit_timeout()); + int timeout = Utils.checkUserTimeout(request.getTimeout(), TIMEOUT_SECONDS, timeoutUnit); + ExecutorService executor = Executors.newSingleThreadExecutor(); + Pair resultAndTime; + try { + var future = executor.submit(() -> processCommand(request)); + resultAndTime = Utils.runServicesWithTimeout(future, timeout, timeoutUnit); + } catch (TimeoutException e) { + LoggerUtil.logger.info("Timeout while running causal reasoner."); + return new CausalReasonerResponse(null, request.getEmail(), timeout, request.getUnit_timeout(), TIMEOUT); + } catch (ExecutionException e) { + LoggerUtil.logger.warning(() -> "Error while running causal reasoner: " + e.getMessage()); + e.printStackTrace(); + throw new RuntimeException(e); + } catch (InterruptedException e) { + LoggerUtil.logger.warning(() -> "Interrupt while running causal reasoner: " + e.getMessage()); + e.printStackTrace(); + Thread.currentThread().interrupt(); + throw new RuntimeException("Thread was interrupted."); + } finally { + executor.shutdownNow(); + } + return new CausalReasonerResponse(resultAndTime.getKey(), request.getEmail(), + resultAndTime.getValue(), request.getUnit_timeout(), SUCCESS); + } + + private String processCommand(CausalReasonerPost post) { + return switch (post.getCmd()) { + case GET_CONCLUSIONS -> processConclusionsCommand(post); + case GET_SIGNIFICANT_ATOMS -> processSignificantAtomsCommand(post); + case GET_ARGUMENTATION_FRAMEWORK -> processArgumentationFramework(post); + case GET_SEQUENCE_EXPLANATIONS -> processSequenceExplanations(post); + }; + } + + private String processConclusionsCommand(CausalReasonerPost post) { + CausalKnowledgeBase kb = parseKnowledgeBase(post); + Collection observations = parseObservations(post); + return causalReasonerService.queryConclusions(kb, observations, parseConclusionFilter(post)).toString(); + } + + private String processSignificantAtomsCommand(CausalReasonerPost post) { + CausalKnowledgeBase kb = parseKnowledgeBase(post); + Collection observations = parseObservations(post); + var perAtomSignificantAtoms = causalReasonerService.queryPerAtomSignificantAtoms(kb, observations, parseConclusionFilter(post)); + Map> jsonData = new HashMap<>(); + for (Map.Entry> entry : perAtomSignificantAtoms.entrySet()) { + List list = new ArrayList<>(); + for (Proposition p : entry.getValue()) + list.add(p.toString()); + jsonData.put(entry.getKey().toString(), list); + } + try { + return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(jsonData); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + private String processSequenceExplanations(CausalReasonerPost post) { + CausalKnowledgeBase kb = parseKnowledgeBase(post); + Collection observations = parseObservations(post); + var reply = SequenceExplanationReply.from(causalReasonerService.querySequenceExplanations(kb, observations, parseConclusionFilter(post))); + try { + return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(reply); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + private String processArgumentationFramework(CausalReasonerPost post) { + CausalKnowledgeBase kb = parseKnowledgeBase(post); + Collection observations = parseObservations(post); + var reply = ArgumentationFrameworkReply.from(causalReasonerService.queryArgumentationFramework(kb, observations)); + try { + return objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(reply); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + + private static Collection parseObservations(CausalReasonerPost post) { + try { + return new CausalParser().parseListOfFormulae(post.getObservations(), ","); + } catch (ParserException e) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, null, e); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private static @Nullable Set parseConclusionFilter(CausalReasonerPost post) { + return ConclusionsFilterSerialization.parse(post.getConclusionsFilter()); + } + + private static CausalKnowledgeBase parseKnowledgeBase(CausalReasonerPost post) { + try { + return new CausalParser().parseBeliefBase(post.getKb()); + } catch (ParserException e) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, null, e); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} From 0feb55959ca3218181f566b915c766bed6c2dff5 Mon Sep 17 00:00:00 2001 From: Lars Bengel Date: Thu, 18 Jun 2026 16:19:55 +0200 Subject: [PATCH 05/14] added webservice for setAFs --- ...va => AbstractSetAfExtensionReasoner.java} | 34 +- .../SimpleAdmissibleSetAfReasoner.java | 2 +- .../SimpleCompleteSetAfReasoner.java | 2 +- .../SimpleConflictFreeSetAfReasoner.java | 2 +- .../reasoners/SimpleEagerSetAfReasoner.java | 2 +- .../SimpleGroundedSetAfReasoner.java | 2 +- .../reasoners/SimpleIdealSetAfReasoner.java | 2 +- .../SimplePreferredSetAfReasoner.java | 2 +- .../SimpleSemiStableSetAfReasoner.java | 2 +- .../reasoners/SimpleStableSetAfReasoner.java | 2 +- .../reasoners/SimpleStageSetAfReasoner.java | 2 +- .../tweetyproject/arg/setaf/syntax/SetAf.java | 10 + org-tweetyproject-web/pom.xml | 7 +- .../web/services/RequestController.java | 47 ++ .../services/setaf/AbstractSetAfFactory.java | 83 ++++ .../setaf/SetAfReasonerCalleeFactory.java | 106 +++++ .../setaf/SetAfReasonerGetModelsCallee.java | 65 +++ .../web/services/setaf/SetAfReasonerPost.java | 196 +++++++++ .../setaf/SetAfReasonerQueryAllCallee.java | 73 ++++ .../services/setaf/SetAfReasonerResponse.java | 411 ++++++++++++++++++ .../setaf/SetAfServicesInfoResponse.java | 244 +++++++++++ .../services/RequestControllerSetAfTest.java | 231 ++++++++++ 22 files changed, 1509 insertions(+), 18 deletions(-) rename org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/{AbstractExtensionSetAfReasoner.java => AbstractSetAfExtensionReasoner.java} (76%) create mode 100644 org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/setaf/AbstractSetAfFactory.java create mode 100644 org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/setaf/SetAfReasonerCalleeFactory.java create mode 100644 org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/setaf/SetAfReasonerGetModelsCallee.java create mode 100644 org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/setaf/SetAfReasonerPost.java create mode 100644 org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/setaf/SetAfReasonerQueryAllCallee.java create mode 100644 org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/setaf/SetAfReasonerResponse.java create mode 100644 org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/setaf/SetAfServicesInfoResponse.java create mode 100644 org-tweetyproject-web/src/test/java/org/tweetyproject/web/services/RequestControllerSetAfTest.java diff --git a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/AbstractExtensionSetAfReasoner.java b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/AbstractSetAfExtensionReasoner.java similarity index 76% rename from org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/AbstractExtensionSetAfReasoner.java rename to org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/AbstractSetAfExtensionReasoner.java index 4f864de23..99aef0adb 100644 --- a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/AbstractExtensionSetAfReasoner.java +++ b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/AbstractSetAfExtensionReasoner.java @@ -19,6 +19,7 @@ package org.tweetyproject.arg.setaf.reasoners; import java.util.Collection; +import java.util.HashSet; import org.tweetyproject.arg.dung.semantics.Extension; import org.tweetyproject.arg.dung.semantics.Semantics; @@ -29,17 +30,17 @@ import org.tweetyproject.commons.postulates.PostulateEvaluatable; /** - * Ancestor class for all SetAf-extension-based reasoners. + * Ancestor class for all SetAF-extension-based reasoners. * * @author Sebastian Franke */ -public abstract class AbstractExtensionSetAfReasoner extends AbstractSetAfReasoner +public abstract class AbstractSetAfExtensionReasoner extends AbstractSetAfReasoner implements ModelProvider>, PostulateEvaluatable { /** * Default constructor for {@code AbstractExtensionSetAfReasoner}. */ - public AbstractExtensionSetAfReasoner() { + public AbstractSetAfExtensionReasoner() { // No specific initialization required } @@ -56,10 +57,29 @@ public Boolean query(SetAf beliefbase, Argument formula) { } /** - * Queries the given AAF for the given argument using the given + * Determine the set of acceptable arguments wrt. the given inference mode + * @param bbase some SetAF + * @param inferenceMode the inference mode + * @return the set of acceptable arguments + */ + public Collection queryAll(SetAf bbase, InferenceMode inferenceMode) { + Collection result = new HashSet<>(); + if(inferenceMode.equals(InferenceMode.CREDULOUS)) + for(Collection extension: this.getModels(bbase)) + result.addAll(extension); + else { + result.addAll(bbase); + for(Collection extension: this.getModels(bbase)) + result.retainAll(extension); + } + return result; + } + + /** + * Queries the given SetAf for the given argument using the given * inference type. * - * @param beliefbase an AAF + * @param beliefbase an SetAF * @param formula a single argument * @param inferenceMode either InferenceMode.SKEPTICAL or * InferenceMode.CREDULOUS @@ -85,9 +105,9 @@ public Boolean query(SetAf beliefbase, Argument formula, InferenceMode inference * Creates a reasoner for the given semantics. * * @param semantics a semantics - * @return a reasoner for the given Dung theory, inference type, and semantics + * @return a reasoner for the given SetAF, inference type, and semantics */ - public static AbstractExtensionSetAfReasoner getSimpleReasonerForSemantics(Semantics semantics) { + public static AbstractSetAfExtensionReasoner getSimpleReasonerForSemantics(Semantics semantics) { switch (semantics) { case CO: return new SimpleCompleteSetAfReasoner(); diff --git a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleAdmissibleSetAfReasoner.java b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleAdmissibleSetAfReasoner.java index d9c794f71..6da8f33cd 100644 --- a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleAdmissibleSetAfReasoner.java +++ b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleAdmissibleSetAfReasoner.java @@ -33,7 +33,7 @@ * @author Matthias Thimm, Sebastian Franke * */ -public class SimpleAdmissibleSetAfReasoner extends AbstractExtensionSetAfReasoner { +public class SimpleAdmissibleSetAfReasoner extends AbstractSetAfExtensionReasoner { /** Default */ public SimpleAdmissibleSetAfReasoner(){ // Default diff --git a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleCompleteSetAfReasoner.java b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleCompleteSetAfReasoner.java index 7641197df..39e07532c 100644 --- a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleCompleteSetAfReasoner.java +++ b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleCompleteSetAfReasoner.java @@ -31,7 +31,7 @@ * @author Matthias Thimm, Sebastian Franke * */ -public class SimpleCompleteSetAfReasoner extends AbstractExtensionSetAfReasoner { +public class SimpleCompleteSetAfReasoner extends AbstractSetAfExtensionReasoner { /** Default */ public SimpleCompleteSetAfReasoner(){ diff --git a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleConflictFreeSetAfReasoner.java b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleConflictFreeSetAfReasoner.java index b208f9ef8..a1e23ace8 100644 --- a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleConflictFreeSetAfReasoner.java +++ b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleConflictFreeSetAfReasoner.java @@ -32,7 +32,7 @@ * @author Matthias Thimm, Sebastian Franke * */ -public class SimpleConflictFreeSetAfReasoner extends AbstractExtensionSetAfReasoner { +public class SimpleConflictFreeSetAfReasoner extends AbstractSetAfExtensionReasoner { /** Default */ diff --git a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleEagerSetAfReasoner.java b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleEagerSetAfReasoner.java index 5abd94b36..8b8d43e3e 100644 --- a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleEagerSetAfReasoner.java +++ b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleEagerSetAfReasoner.java @@ -33,7 +33,7 @@ * * @author Lars Bengel, Sebastian Franke */ -public class SimpleEagerSetAfReasoner extends AbstractExtensionSetAfReasoner { +public class SimpleEagerSetAfReasoner extends AbstractSetAfExtensionReasoner { /** Default */ diff --git a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleGroundedSetAfReasoner.java b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleGroundedSetAfReasoner.java index ab6f4a5ff..b5b1b59fb 100644 --- a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleGroundedSetAfReasoner.java +++ b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleGroundedSetAfReasoner.java @@ -32,7 +32,7 @@ * @author Matthias Thimm, Sebastian Franke * */ -public class SimpleGroundedSetAfReasoner extends AbstractExtensionSetAfReasoner { +public class SimpleGroundedSetAfReasoner extends AbstractSetAfExtensionReasoner { /** Default */ public SimpleGroundedSetAfReasoner(){ diff --git a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleIdealSetAfReasoner.java b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleIdealSetAfReasoner.java index bd5c08dd4..f0ac32508 100644 --- a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleIdealSetAfReasoner.java +++ b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleIdealSetAfReasoner.java @@ -32,7 +32,7 @@ * @author Matthias Thimm, Sebastian Franke * */ -public class SimpleIdealSetAfReasoner extends AbstractExtensionSetAfReasoner { +public class SimpleIdealSetAfReasoner extends AbstractSetAfExtensionReasoner { diff --git a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimplePreferredSetAfReasoner.java b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimplePreferredSetAfReasoner.java index 0eb12b846..359d98175 100644 --- a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimplePreferredSetAfReasoner.java +++ b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimplePreferredSetAfReasoner.java @@ -33,7 +33,7 @@ * @author Matthias Thimm, Sebastian Franke * */ -public class SimplePreferredSetAfReasoner extends AbstractExtensionSetAfReasoner { +public class SimplePreferredSetAfReasoner extends AbstractSetAfExtensionReasoner { diff --git a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleSemiStableSetAfReasoner.java b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleSemiStableSetAfReasoner.java index f0b475c08..c4a695134 100644 --- a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleSemiStableSetAfReasoner.java +++ b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleSemiStableSetAfReasoner.java @@ -33,7 +33,7 @@ * @author Matthias Thimm, Sebastian Franke * */ -public class SimpleSemiStableSetAfReasoner extends AbstractExtensionSetAfReasoner { +public class SimpleSemiStableSetAfReasoner extends AbstractSetAfExtensionReasoner { /** Default */ diff --git a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleStableSetAfReasoner.java b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleStableSetAfReasoner.java index 8e8cb9cd9..2d7abee48 100644 --- a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleStableSetAfReasoner.java +++ b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleStableSetAfReasoner.java @@ -31,7 +31,7 @@ * @author Matthias Thimm, Sebastian Franke * */ -public class SimpleStableSetAfReasoner extends AbstractExtensionSetAfReasoner { +public class SimpleStableSetAfReasoner extends AbstractSetAfExtensionReasoner { diff --git a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleStageSetAfReasoner.java b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleStageSetAfReasoner.java index d82b1a6cf..584accedc 100644 --- a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleStageSetAfReasoner.java +++ b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/reasoners/SimpleStageSetAfReasoner.java @@ -32,7 +32,7 @@ * @author Matthias Thimm, Sebastian Franke * */ -public class SimpleStageSetAfReasoner extends AbstractExtensionSetAfReasoner { +public class SimpleStageSetAfReasoner extends AbstractSetAfExtensionReasoner { diff --git a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/syntax/SetAf.java b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/syntax/SetAf.java index f90509927..965f3b76a 100644 --- a/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/syntax/SetAf.java +++ b/org-tweetyproject-arg-setaf/src/main/java/org/tweetyproject/arg/setaf/syntax/SetAf.java @@ -432,6 +432,16 @@ public boolean add(SetAttack edge) { return true; } + /** + * Add a new set-attack so the theory + * @param attackers the set of attacking arguments + * @param attacked the attacked argument + * @return "true" if the set-attack has been added + */ + public boolean addSetAttack(Set attackers, Argument attacked) { + return this.add(new SetAttack(attackers, attacked)); + } + @Override public Collection getNodes() { return this.nodes; diff --git a/org-tweetyproject-web/pom.xml b/org-tweetyproject-web/pom.xml index 342822e12..7964bea55 100644 --- a/org-tweetyproject-web/pom.xml +++ b/org-tweetyproject-web/pom.xml @@ -159,8 +159,13 @@ prob 1.30-SNAPSHOT + + org.tweetyproject.arg + setaf + 1.30-SNAPSHOT + -