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 ad48e3845..93eddd65e 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
@@ -44,6 +44,7 @@
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ResponseStatusException;
+import org.tweetyproject.arg.bipolar.reasoner.AbstractBipolarExtensionReasoner;
import org.tweetyproject.arg.dung.syntax.Argument;
import org.tweetyproject.arg.dung.syntax.Attack;
import org.tweetyproject.arg.dung.syntax.DungTheory;
@@ -79,6 +80,7 @@
import org.tweetyproject.web.services.aba.AbaReasonerPost;
import org.tweetyproject.web.services.aba.AbaReasonerResponse;
import org.tweetyproject.web.services.aba.GeneralAbaReasonerFactory;
+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;
@@ -426,6 +428,111 @@ public DungServicesInfoResponse getInfo(@RequestBody DungReasonerPost dungPost)
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")) {
+ var semantics = BipolarSemantics.getSemantics(bipolarReasonerPost.getSemantics());
+ var bbase = AbstractBipolarFrameworkFactory.getArgumentationFramework(
+ semantics,
+ bipolarReasonerPost.getNr_of_arguments(),
+ bipolarReasonerPost.getAttacks(),
+ bipolarReasonerPost.getSupports());
+ 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.getTimoutUnit(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");
+
+ executor.shutdownNow();
+ }
+ return reasonerResponse;
+ } else {
+ return new BipolarReasonerResponse();
+ }
+ }
+
+ private BipolarServicesInfoResponse getBipolarInfo(String email) {
+ BipolarServicesInfoResponse response = new BipolarServicesInfoResponse();
+ 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) {
+ semantics_ids.add(s.id);
+ }
+ response.setSemantics(semantics_ids);
+
+ BipolarReasonerCalleeFactory.Command[] com = BipolarReasonerCalleeFactory.getCommands();
+ ArrayList command_ids = new ArrayList();
+ for (var c : com) {
+ command_ids.add(c.id);
+ }
+ response.setCommands(command_ids);
+
+ return response;
+ }
+
+
/**
* Handles HTTP POST requests for Defeasible logic programming DeLP Reasoner operations.
*
diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/AbstractBipolarExtensionReasonerFactory.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/AbstractBipolarExtensionReasonerFactory.java
index aa7ea3804..94a5bd84a 100644
--- a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/AbstractBipolarExtensionReasonerFactory.java
+++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/AbstractBipolarExtensionReasonerFactory.java
@@ -23,58 +23,18 @@
import org.tweetyproject.arg.bipolar.reasoner.necessity.*;
/**
- * Main factory for retrieving bipolar extension reasoners.
+ * Main factory for retrieving bipolar extension reasoners as supported by the web service
*
* @author Lars Bengel
*/
public abstract class AbstractBipolarExtensionReasonerFactory {
-
- /** An enumeration of all available semantics. */
- public enum Semantics {
- /** General Semantics */
- CF("cf", "Conflict-Free"),
- SA("sa", "Safe"),
- CL("cl", "Closed"),
- /** Semantics for Deductive Interpretation */
- CAD("c-ad", "c-Admissible"),
- DAD("d-ad", "d-Admissible"),
- /** Semantics for Necessary Interpretation */
- NAD("n-ad", "Admissible"),
- NCO("n-co", "Complete"),
- NGR("n-gr", "Grounded"),
- NPR("n-pr", "Preferred"),
- NST("n-st", "Stable");
-
- /** id */
- public String id;
- /** label */
- public String label;
-
- Semantics(String id, String label) {
- this.id = id;
- this.label = label;
- }
-
- /**
- *
- * @param id ID
- * @return the semantics
- */
- public static Semantics getSemantics(String id) {
- for (Semantics m : Semantics.values())
- if (m.id.equals(id))
- return m;
- return null;
- }
- }
-
/**
* Returns an array of all available semantics.
*
* @return An array of all available semantics.
*/
- public static Semantics[] getSemantics() {
- return Semantics.values();
+ public static BipolarSemantics[] getSemantics() {
+ return BipolarSemantics.values();
}
/**
@@ -84,7 +44,7 @@ public static Semantics[] getSemantics() {
* @param sem some identifier of an semantics.
* @return the requested reasoner.
*/
- public static AbstractBipolarExtensionReasoner getReasoner(Semantics sem) {
+ public static AbstractBipolarExtensionReasoner getReasoner(BipolarSemantics sem) {
return switch (sem) {
case CF -> new ConflictFreeReasoner();
case SA -> new SafetyReasoner();
diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/AbstractBipolarFrameworkFactory.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/AbstractBipolarFrameworkFactory.java
new file mode 100644
index 000000000..11c18026b
--- /dev/null
+++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/AbstractBipolarFrameworkFactory.java
@@ -0,0 +1,77 @@
+/*
+ * 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.bipolar;
+
+import org.tweetyproject.arg.bipolar.reasoner.deductive.*;
+import org.tweetyproject.arg.bipolar.reasoner.necessity.*;
+import org.tweetyproject.arg.bipolar.syntax.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Factory for construction bipolar argumentation framework from web requests.
+ *
+ * @author Oleksandr Dzhychko
+ */
+public abstract class AbstractBipolarFrameworkFactory {
+
+
+ /**
+ * Creates a new bipolar argumentation framework required fo the given semantics.
+ *
+ * @param semantics specified semantics
+ * @param numberOfArguments number of arguments
+ * @param attacks attacks
+ * @param supports supports
+ * @return the requested reasoner.
+ */
+ public static AbstractBipolarFramework getArgumentationFramework(BipolarSemantics semantics,
+ int numberOfArguments,
+ List> attacks,
+ List> supports) {
+ var argumentationFramework = switch (semantics.input) {
+ case DeductiveArgumentationFramework -> new DeductiveArgumentationFramework();
+ case NecessityArgumentationFramework -> new NecessityArgumentationFramework();
+ };
+
+ var arguments = new ArrayList();
+ for (int i = 1; i <= numberOfArguments; i++){
+ var argument = new BArgument(Integer.toString(i));
+ arguments.add(argument);
+ argumentationFramework.add(argument);
+ }
+
+ for (List attackInput : attacks) {
+ var attacker = arguments.get(attackInput.get(0) - 1);
+ var attacked = arguments.get(attackInput.get(1) - 1);
+ Attack attack = new BinaryAttack(attacker, attacked);
+ argumentationFramework.add(attack);
+ }
+
+ for (List supportInput : supports) {
+ var supporter = arguments.get(supportInput.get(0) - 1);
+ var supported = arguments.get(supportInput.get(1) - 1);
+ Support attack = new BinarySupport(supporter, supported);
+ argumentationFramework.add(attack);
+ }
+
+ return argumentationFramework;
+ }
+}
diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarArgumentationFrameworkType.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarArgumentationFrameworkType.java
new file mode 100644
index 000000000..f51ceace5
--- /dev/null
+++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarArgumentationFrameworkType.java
@@ -0,0 +1,27 @@
+/*
+ * 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.bipolar;
+
+/**
+ * @author Oleksandr Dzhychko
+ */
+public enum BipolarArgumentationFrameworkType {
+ DeductiveArgumentationFramework,
+ NecessityArgumentationFramework,
+}
diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarReasonerCalleeFactory.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarReasonerCalleeFactory.java
new file mode 100644
index 000000000..9fcc23f9c
--- /dev/null
+++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarReasonerCalleeFactory.java
@@ -0,0 +1,101 @@
+/*
+ * 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.bipolar;
+
+import org.tweetyproject.arg.bipolar.reasoner.AbstractBipolarExtensionReasoner;
+import org.tweetyproject.arg.bipolar.syntax.AbstractBipolarFramework;
+import org.tweetyproject.web.services.Callee;
+
+
+/**
+ * The BipolarReasonerCalleeFactory class is responsible for creating instances of Callee
+ * based on the specified Command, AbstractBipolarExtensionReasoner, and AbstractBipolarFramework parameters.
+ * It also defines an enumeration of commands with associated IDs and labels.
+ */
+public class BipolarReasonerCalleeFactory {
+
+ /**
+ * Enumeration of commands supported by the factory, each with a unique ID and label.
+ */
+ public enum Command {
+ /** get models */
+ GET_MODELS("get_models", "Get all models"),
+ /** get model */
+ GET_MODEL("get_model", "Get some model");
+
+ /** ID of the command */
+ public String id;
+ /** Label of the command */
+ public 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, AbstractBipolarExtensionReasoner,
+ * and AbstractBipolarFramework parameters.
+ *
+ * @param cmd The command to be executed
+ * @param reasoner The AbstractBipolarExtensionReasoner to be used
+ * @param bbase The AbstractBipolarFramework 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, AbstractBipolarExtensionReasoner reasoner, AbstractBipolarFramework bbase) {
+ switch (cmd) {
+ case GET_MODELS:
+ return new BipolarReasonerGetModelsCallee(reasoner, bbase);
+ case GET_MODEL:
+ return new BipolarReasonerGetModelCallee(reasoner, bbase);
+ default:
+ throw new RuntimeException("Command not found: " + cmd.toString());
+ }
+ }
+}
diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarReasonerGetModelCallee.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarReasonerGetModelCallee.java
new file mode 100644
index 000000000..877e1e4f2
--- /dev/null
+++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarReasonerGetModelCallee.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.bipolar;
+
+import org.tweetyproject.arg.bipolar.reasoner.AbstractBipolarExtensionReasoner;
+import org.tweetyproject.arg.bipolar.syntax.AbstractBipolarFramework;
+import org.tweetyproject.arg.bipolar.syntax.BArgument;
+import org.tweetyproject.web.services.Callee;
+
+import java.util.Collection;
+
+/**
+ * The BipolarReasonerGetModelCallee class represents a callee for obtaining a model
+ * using a specified AbstractBipolarExtensionReasoner and AbstractBipolarFramework.
+ *
+ * This class extends the Callee class and implements the call() method to execute
+ * the getModel operation using the provided reasoner and base AbstractBipolarFramework.
+ */
+public class BipolarReasonerGetModelCallee extends Callee {
+
+ /** The AbstractBipolarExtensionReasoner used for obtaining the model */
+ private AbstractBipolarExtensionReasoner reasoner;
+
+ /** The AbstractBipolarFramework on which the getModel operation is performed */
+ private AbstractBipolarFramework bbase;
+
+ /**
+ * Constructs a new BipolarReasonerGetModelCallee with the specified reasoner and base AbstractBipolarFramework.
+ *
+ * @param reasoner The AbstractBipolarExtensionReasoner to be used for obtaining the model
+ * @param bbase The base AbstractBipolarFramework on which the getModel operation is performed
+ */
+ public BipolarReasonerGetModelCallee(AbstractBipolarExtensionReasoner reasoner, AbstractBipolarFramework bbase) {
+ this.reasoner = reasoner;
+ this.bbase = bbase;
+ }
+
+ /**
+ * Executes the getModel operation using the specified reasoner and base AbstractBipolarFramework.
+ *
+ * @return An Extension representing the obtained model
+ * @throws Exception If an error occurs during the getModel operation
+ */
+ @Override
+ public Collection call() throws Exception {
+ return this.reasoner.getModel(this.bbase);
+ }
+}
\ No newline at end of file
diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarReasonerGetModelsCallee.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarReasonerGetModelsCallee.java
new file mode 100644
index 000000000..7813527ae
--- /dev/null
+++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarReasonerGetModelsCallee.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.bipolar;
+
+import org.tweetyproject.arg.bipolar.reasoner.AbstractBipolarExtensionReasoner;
+import org.tweetyproject.arg.bipolar.syntax.BArgument;
+import org.tweetyproject.arg.bipolar.syntax.AbstractBipolarFramework;
+import org.tweetyproject.web.services.Callee;
+
+import java.util.Collection;
+
+/**
+ * The BipolarReasonerGetModelsCallee class represents a callee for obtaining multiple models
+ * using a specified AbstractBipolarExtensionReasoner and AbstractBipolarFramework.
+ *
+ * This class extends the Callee class and implements the call() method to execute
+ * the getModels operation using the provided reasoner and base AbstractBipolarFramework.
+ */
+public class BipolarReasonerGetModelsCallee extends Callee {
+
+ /** The AbstractBipolarExtensionReasoner used for obtaining multiple models */
+ private AbstractBipolarExtensionReasoner reasoner;
+
+ /** The AbstractBipolarFramework on which the getModels operation is performed */
+ private AbstractBipolarFramework bbase;
+
+ /**
+ * Constructs a new BipolarReasonerGetModelsCallee with the specified reasoner and base AbstractBipolarFramework.
+ *
+ * @param reasoner The AbstractBipolarExtensionReasoner to be used for obtaining multiple models
+ * @param bbase The base AbstractBipolarFramework on which the getModels operation is performed
+ */
+ public BipolarReasonerGetModelsCallee(AbstractBipolarExtensionReasoner reasoner, AbstractBipolarFramework bbase) {
+ this.reasoner = reasoner;
+ this.bbase = bbase;
+ }
+
+ /**
+ * Executes the getModels operation using the specified reasoner and base AbstractBipolarFramework.
+ *
+ * @return A collection of Extensions representing the obtained models
+ * @throws Exception If an error occurs during the getModels operation
+ */
+ @Override
+ public Collection> call() throws Exception {
+ return this.reasoner.getModels(this.bbase);
+ }
+}
\ No newline at end of file
diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarReasonerPost.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarReasonerPost.java
new file mode 100644
index 000000000..b428618bc
--- /dev/null
+++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarReasonerPost.java
@@ -0,0 +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.bipolar;
+
+import java.util.List;
+
+/**
+ * The BipolarReasonerPost class represents a data structure for holding information
+ * related to a bipolar argumentation reasoner request sent via HTTP POST.
+ */
+public class BipolarReasonerPost {
+
+ /** The command type for the bipolar reasoner request */
+ private String cmd;
+
+ /** The email associated with the bipolar reasoner request */
+ private String email;
+
+ /** The number of arguments in the bipolar reasoner request */
+ private int nr_of_arguments;
+
+ /** The attacks information in the bipolar reasoner request */
+ private List> attacks;
+
+ /** The supports information in the bipolar reasoner request */
+ private List> supports;
+
+ /** The semantics specified in the bipolar reasoner request */
+ private String semantics;
+
+ /** The solver specified in the bipolar reasoner request */
+ private String solver;
+
+ /** The timeout value (in seconds) specified in the bipolar reasoner request */
+ private int timeout;
+
+ /** The unit timeout value specified in the bipolar reasoner request */
+ private String unit_timeout;
+
+ /**
+ * Gets the unit timeout value specified in the bipolar reasoner request.
+ *
+ * @return The unit timeout value
+ */
+ public String getUnit_timeout() {
+ return unit_timeout;
+ }
+
+ /**
+ * Sets the unit timeout value in the bipolar reasoner 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 bipolar reasoner request.
+ *
+ * @return The command type
+ */
+ public String getCmd() {
+ return this.cmd;
+ }
+
+ /**
+ * Sets the command type in the bipolar reasoner request.
+ *
+ * @param cmd The command type to be set
+ */
+ public void setCmd(String cmd) {
+ this.cmd = cmd;
+ }
+
+ /**
+ * Gets the email associated with the bipolar reasoner request.
+ *
+ * @return The email associated with the request
+ */
+ public String getEmail() {
+ return this.email;
+ }
+
+ /**
+ * Sets the email associated with the bipolar reasoner request.
+ *
+ * @param email The email to be set
+ */
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ /**
+ * Gets the number of arguments in the bipolar reasoner request.
+ *
+ * @return The number of arguments
+ */
+ public int getNr_of_arguments() {
+ return this.nr_of_arguments;
+ }
+
+ /**
+ * Sets the number of arguments in the bipolar reasoner 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 bipolar reasoner request.
+ *
+ * @return The attacks information
+ */
+ public List> getAttacks() {
+ return this.attacks;
+ }
+
+ /**
+ * Sets the attacks information in the bipolar reasoner request.
+ *
+ * @param attacks The attacks information to be set
+ */
+ public void setAttacks(List> attacks) {
+ this.attacks = attacks;
+ }
+
+ /**
+ * Gets the supports information in the bipolar reasoner request.
+ *
+ * @return The supports information
+ */
+ public List> getSupports() {
+ return this.supports;
+ }
+
+ /**
+ * Sets the supports information in the bipolar reasoner request.
+ *
+ * @param supports The supports information to be set
+ */
+ public void setSupports(List> supports) {
+ this.supports = supports;
+ }
+
+ /**
+ * Gets the semantics specified in the bipolar reasoner request.
+ *
+ * @return The semantics specified
+ */
+ public String getSemantics() {
+ return this.semantics;
+ }
+
+ /**
+ * Sets the semantics in the bipolar reasoner request.
+ *
+ * @param semantics The semantics to be set
+ */
+ public void setSemantics(String semantics) {
+ this.semantics = semantics;
+ }
+
+ /**
+ * Gets the solver specified in the bipolar reasoner request.
+ *
+ * @return The solver specified
+ */
+ public String getSolver() {
+ return this.solver;
+ }
+
+ /**
+ * Sets the solver in the bipolar reasoner request.
+ *
+ * @param solver The solver to be set
+ */
+ public void setSolver(String solver) {
+ this.solver = solver;
+ }
+
+ /**
+ * Gets the timeout value (in seconds) specified in the bipolar reasoner request.
+ *
+ * @return The timeout value
+ */
+ public int getTimeout() {
+ return this.timeout;
+ }
+
+ /**
+ * Sets the timeout value (in seconds) in the bipolar reasoner 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/bipolar/BipolarReasonerResponse.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarReasonerResponse.java
new file mode 100644
index 000000000..b5c5a67ff
--- /dev/null
+++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarReasonerResponse.java
@@ -0,0 +1,421 @@
+/*
+ * 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.bipolar;
+
+import org.tweetyproject.web.services.Response;
+
+import java.util.List;
+
+/**
+ * The BipolarReasonerResponse class extends the Response class and represents
+ * a response containing information related to a bipolar argumentation reasoner
+ * result.
+ */
+public class BipolarReasonerResponse extends Response {
+
+ /** The reply message in the bipolar reasoner response */
+ private String reply;
+
+ /** The email associated with the bipolar reasoner response */
+ private String email;
+
+ /** The number of arguments in the bipolar reasoner response */
+ private int nr_of_arguments;
+
+ /** The attacks information in the bipolar reasoner response */
+ private List> attacks;
+
+ /** The supports information in the bipolar reasoner response */
+ private List> supports;
+
+ /** The semantics specified in the bipolar reasoner response */
+ private String semantics;
+
+ /** The solver specified in the bipolar reasoner response */
+ private String solver;
+
+ /** The answer provided by the bipolar reasoner response */
+ private String answer;
+
+ /** The time taken for the bipolar reasoner operation (in seconds) */
+ private double time;
+
+ /** The unit time specified in the bipolar reasoner response */
+ private String unit_time;
+
+ /** The status of the bipolar reasoner response */
+ private String status;
+
+ /**
+ * Default constructor for BipolarReasonerResponse.
+ */
+ public BipolarReasonerResponse() {
+ }
+
+ /**
+ * Parameterized constructor for BipolarReasonerResponse.
+ *
+ * @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 semantics The semantics specified
+ * @param solver 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 BipolarReasonerResponse(String reply,
+ String email,
+ int nr_of_arguments,
+ List> attacks,
+ List> supports,
+ String semantics,
+ String solver,
+ 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.supports = supports;
+ this.semantics = semantics;
+ this.solver = solver;
+ this.answer = answer;
+ this.time = time;
+ this.unit_time = unit_time;
+ this.status = status;
+ }
+
+ /**
+ * Gets the reply message in the bipolar reasoner response.
+ *
+ * @return The reply message in the bipolar reasoner response.
+ */
+ public String getReply() {
+ return reply;
+ }
+
+ /**
+ * Sets the reply message in the bipolar reasoner response.
+ *
+ * @param reply The reply message in the bipolar reasoner response.
+ */
+ public void setReply(String reply) {
+ this.reply = reply;
+ }
+
+ /**
+ * Gets the email associated with the bipolar reasoner response.
+ *
+ * @return The email associated with the bipolar reasoner response.
+ */
+ public String getEmail() {
+ return email;
+ }
+
+ /**
+ * Sets the email associated with the bipolar reasoner response.
+ *
+ * @param email The email associated with the bipolar reasoner response.
+ */
+ public void setEmail(String email) {
+ this.email = email;
+ }
+
+ /**
+ * Gets the number of arguments in the bipolar reasoner response.
+ *
+ * @return The number of arguments in the bipolar reasoner response.
+ */
+ public int getNr_of_arguments() {
+ return nr_of_arguments;
+ }
+
+ /**
+ * Sets the number of arguments in the bipolar reasoner response.
+ *
+ * @param nr_of_arguments The number of arguments in the bipolar reasoner response.
+ */
+ public void setNr_of_arguments(int nr_of_arguments) {
+ this.nr_of_arguments = nr_of_arguments;
+ }
+
+ /**
+ * Gets the attacks information in the bipolar reasoner response.
+ *
+ * @return The attacks information in the bipolar reasoner response.
+ */
+ public List> getAttacks() {
+ return attacks;
+ }
+
+ /**
+ * Sets the attacks information in the bipolar reasoner response.
+ *
+ * @param attacks The attacks information in the bipolar reasoner response.
+ */
+ public void setAttacks(List> attacks) {
+ this.attacks = attacks;
+ }
+
+ /**
+ * Gets the supports information in the bipolar reasoner response.
+ *
+ * @return The supports information in the bipolar reasoner response.
+ */
+ public List> getSupports() {
+ return supports;
+ }
+
+ /**
+ * Sets the supports information in the bipolar reasoner response.
+ *
+ * @param supports The supports information in the bipolar reasoner response.
+ */
+ public void setSupports(List> supports) {
+ this.supports = supports;
+ }
+
+ /**
+ * Gets the semantics specified in the bipolar reasoner response.
+ *
+ * @return The semantics specified in the bipolar reasoner response.
+ */
+ public String getSemantics() {
+ return semantics;
+ }
+
+ /**
+ * Sets the semantics specified in the bipolar reasoner response.
+ *
+ * @param semantics The semantics specified in the bipolar reasoner response.
+ */
+ public void setSemantics(String semantics) {
+ this.semantics = semantics;
+ }
+
+ /**
+ * Gets the solver specified in the bipolar reasoner response.
+ *
+ * @return The solver specified in the bipolar reasoner response.
+ */
+ public String getSolver() {
+ return solver;
+ }
+
+ /**
+ * Sets the solver specified in the bipolar reasoner response.
+ *
+ * @param solver The solver specified in the bipolar reasoner response.
+ */
+ public void setSolver(String solver) {
+ this.solver = solver;
+ }
+
+ /**
+ * Gets the answer provided by the bipolar reasoner response.
+ *
+ * @return The answer provided by the bipolar reasoner response.
+ */
+ public String getAnswer() {
+ return answer;
+ }
+
+ /**
+ * Sets the answer provided by the bipolar reasoner response.
+ *
+ * @param answer The answer provided by the bipolar reasoner response.
+ */
+ public void setAnswer(String answer) {
+ this.answer = answer;
+ }
+
+ /**
+ * Gets the time taken for the bipolar reasoner operation (in seconds).
+ *
+ * @return The time taken for the bipolar reasoner operation (in seconds).
+ */
+ public double getTime() {
+ return time;
+ }
+
+ /**
+ * Sets the time taken for the bipolar reasoner operation (in seconds).
+ *
+ * @param time The time taken for the bipolar reasoner operation (in seconds).
+ */
+ public void setTime(double time) {
+ this.time = time;
+ }
+
+ /**
+ * Gets the unit time specified in the bipolar reasoner response.
+ *
+ * @return The unit time specified in the bipolar reasoner response.
+ */
+ public String getUnit_time() {
+ return unit_time;
+ }
+
+ /**
+ * Sets the unit time specified in the bipolar reasoner response.
+ *
+ * @param unit_time The unit time specified in the bipolar reasoner response.
+ */
+ public void setUnit_time(String unit_time) {
+ this.unit_time = unit_time;
+ }
+
+ /**
+ * Gets the status of the bipolar reasoner response.
+ *
+ * @return The status of the bipolar reasoner response.
+ */
+ public String getStatus() {
+ return status;
+ }
+
+ /**
+ * Sets the status of the bipolar reasoner response.
+ *
+ * @param status The status of the bipolar reasoner response.
+ */
+ public void setStatus(String status) {
+ this.status = status;
+ }
+
+ /**
+ * Sets the reply message in the bipolar reasoner response.
+ *
+ * @param reply The reply message in the bipolar reasoner response.
+ * @return The current instance of BipolarReasonerResponse.
+ */
+ public BipolarReasonerResponse reply(String reply) {
+ setReply(reply);
+ return this;
+ }
+
+ /**
+ * Sets the email associated with the bipolar reasoner response.
+ *
+ * @param email The email associated with the bipolar reasoner response.
+ * @return The current instance of BipolarReasonerResponse.
+ */
+ public BipolarReasonerResponse email(String email) {
+ setEmail(email);
+ return this;
+ }
+
+ /**
+ * Sets the number of arguments in the bipolar reasoner response.
+ *
+ * @param nr_of_arguments The number of arguments in the bipolar reasoner response.
+ * @return The current instance of BipolarReasonerResponse.
+ */
+ public BipolarReasonerResponse nr_of_arguments(int nr_of_arguments) {
+ setNr_of_arguments(nr_of_arguments);
+ return this;
+ }
+
+ /**
+ * Sets the attacks information in the bipolar reasoner response.
+ *
+ * @param attacks The attacks information in the bipolar reasoner response.
+ * @return The current instance of BipolarReasonerResponse.
+ */
+ public BipolarReasonerResponse attacks(List> attacks) {
+ setAttacks(attacks);
+ return this;
+ }
+
+ /**
+ * Sets the semantics specified in the bipolar reasoner response.
+ *
+ * @param semantics The semantics specified in the bipolar reasoner response.
+ * @return The current instance of BipolarReasonerResponse.
+ */
+ public BipolarReasonerResponse semantics(String semantics) {
+ setSemantics(semantics);
+ return this;
+ }
+
+ /**
+ * Sets the solver specified in the bipolar reasoner response.
+ *
+ * @param solver The solver specified in the bipolar reasoner response.
+ * @return The current instance of BipolarReasonerResponse.
+ */
+ public BipolarReasonerResponse solver(String solver) {
+ setSolver(solver);
+ return this;
+ }
+
+ /**
+ * Sets the answer provided by the bipolar reasoner response.
+ *
+ * @param answer The answer provided by the bipolar reasoner response.
+ * @return The current instance of BipolarReasonerResponse.
+ */
+ public BipolarReasonerResponse answer(String answer) {
+ setAnswer(answer);
+ return this;
+ }
+
+ /**
+ * Sets the time taken for the bipolar reasoner operation (in seconds).
+ *
+ * @param time The time taken for the bipolar reasoner operation (in seconds).
+ * @return The current instance of BipolarReasonerResponse.
+ */
+ public BipolarReasonerResponse time(int time) {
+ setTime(time);
+ return this;
+ }
+
+ /**
+ * Sets the status of the bipolar reasoner response.
+ *
+ * @param status The status of the bipolar reasoner response.
+ * @return The current instance of BipolarReasonerResponse.
+ */
+ public BipolarReasonerResponse status(String status) {
+ setStatus(status);
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return "{" +
+ " reply='" + getReply() + "'" +
+ ", email='" + getEmail() + "'" +
+ ", nr_of_arguments='" + getNr_of_arguments() + "'" +
+ ", attacks='" + getAttacks() + "'" +
+ ", semantics='" + getSemantics() + "'" +
+ ", solver='" + getSolver() + "'" +
+ ", answer='" + getAnswer() + "'" +
+ ", time='" + getTime() + "'" +
+ ", status='" + getStatus() + "'" +
+ "}";
+ }
+
+}
\ No newline at end of file
diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarSemantics.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarSemantics.java
new file mode 100644
index 000000000..e800d3b4b
--- /dev/null
+++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarSemantics.java
@@ -0,0 +1,81 @@
+/*
+ * 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.bipolar;
+
+import static org.tweetyproject.web.services.bipolar.BipolarArgumentationFrameworkType.DeductiveArgumentationFramework;
+import static org.tweetyproject.web.services.bipolar.BipolarArgumentationFrameworkType.NecessityArgumentationFramework;
+
+/**
+ * An enumeration of all available semantics through the web service.
+ *
+ * @author Oleksandr Dzhychko
+ */
+public enum BipolarSemantics {
+
+ /**
+ * General Semantics
+ */
+ CF("cf", "Conflict-Free", DeductiveArgumentationFramework),
+ SA("sa", "Safe", DeductiveArgumentationFramework),
+ CL("cl", "Closed", DeductiveArgumentationFramework),
+ /**
+ * Semantics for Deductive Interpretation
+ */
+ CAD("c-ad", "c-Admissible", DeductiveArgumentationFramework),
+ DAD("d-ad", "d-Admissible", DeductiveArgumentationFramework),
+ /**
+ * Semantics for Necessary Interpretation
+ */
+ NAD("n-ad", "Admissible", NecessityArgumentationFramework),
+ NCO("n-co", "Complete", NecessityArgumentationFramework),
+ NGR("n-gr", "Grounded", NecessityArgumentationFramework),
+ NPR("n-pr", "Preferred", NecessityArgumentationFramework),
+ NST("n-st", "Stable", NecessityArgumentationFramework);
+
+ /**
+ * id
+ */
+ public String id;
+ /**
+ * label
+ */
+ public String label;
+ /**
+ * What type of input is expected for this semantic.
+ */
+ public BipolarArgumentationFrameworkType input;
+
+ BipolarSemantics(String id, String label, BipolarArgumentationFrameworkType input) {
+ this.id = id;
+ this.label = label;
+ this.input = input;
+ }
+
+ /**
+ *
+ * @param id ID
+ * @return the semantics
+ */
+ public static BipolarSemantics getSemantics(String id) {
+ for (BipolarSemantics m : BipolarSemantics.values())
+ if (m.id.equals(id))
+ return m;
+ return null;
+ }
+}
\ No newline at end of file
diff --git a/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarServicesInfoResponse.java b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarServicesInfoResponse.java
new file mode 100644
index 000000000..521fd39ff
--- /dev/null
+++ b/org-tweetyproject-web/src/main/java/org/tweetyproject/web/services/bipolar/BipolarServicesInfoResponse.java
@@ -0,0 +1,226 @@
+/*
+ * 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.bipolar;
+
+import org.tweetyproject.web.services.Response;
+
+import java.util.List;
+
+/**
+ * The BipolarServicesInfoResponse class extends the Response class and represents
+ * a response containing information about bipolar argumentation services.
+ */
+public class BipolarServicesInfoResponse extends Response {
+
+ /** The reply message in the bipolar services info response */
+ private String reply;
+
+ /** The email associated with the bipolar services info response */
+ private String email;
+
+ /** The backend timeout value specified in the bipolar services info response */
+ private int backend_timeout;
+
+ /** The list of supported semantics in the bipolar services info response */
+ private List semantics;
+
+ /** The list of supported commands in the bipolar services info response */
+ private List commands;
+
+ /**
+ * Default constructor for BipolarServicesInfoResponse .
+ */
+ public BipolarServicesInfoResponse() {
+ }
+
+ /**
+ * Parameterized constructor for BipolarServicesInfoResponse .
+ *
+ * @param reply The reply message
+ * @param email The email associated with the response
+ * @param backend_timeout The backend timeout value
+ * @param semantics The list of supported semantics
+ * @param commands The list of supported commands
+ */
+ public BipolarServicesInfoResponse(String reply, String email, int backend_timeout, List semantics, List commands) {
+ this.reply = reply;
+ this.email = email;
+ this.backend_timeout = backend_timeout;
+ this.semantics = semantics;
+ 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 semantic elements associated with the service.
+ *
+ * @return A list of semantics as strings.
+ */
+ public List getSemantics() {
+ return this.semantics;
+ }
+
+ /**
+ * Sets the list of semantic elements for the service.
+ *
+ * @param semantics A list of semantic strings to be used or defined by the service.
+ */
+ public void setSemantics(List semantics) {
+ this.semantics = semantics;
+ }
+
+ /**
+ * 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;
+ }
+
+ // 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 BipolarServicesInfoResponse 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 BipolarServicesInfoResponse 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 BipolarServicesInfoResponse backend_timeout(int backend_timeout) {
+ setBackend_timeout(backend_timeout);
+ return this;
+ }
+
+ /**
+ * Sets the semantics and returns this instance for method chaining.
+ *
+ * @param semantics A list of semantic strings to set.
+ * @return This instance to facilitate further modifications.
+ */
+ public BipolarServicesInfoResponse semantics(List semantics) {
+ setSemantics(semantics);
+ 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 BipolarServicesInfoResponse commands(List commands) {
+ setCommands(commands);
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return "{" +
+ " reply='" + getReply() + "'" +
+ ", email='" + getEmail() + "'" +
+ ", backend_timeout='" + getBackend_timeout() + "'" +
+ ", semantics='" + getSemantics() + "'" +
+ ", commands='" + getCommands() + "'" +
+ "}";
+ }
+}
diff --git a/org-tweetyproject-web/src/test/java/org/tweetyproject/web/services/RequestControllerBipolarTest.java b/org-tweetyproject-web/src/test/java/org/tweetyproject/web/services/RequestControllerBipolarTest.java
new file mode 100644
index 000000000..8015528f5
--- /dev/null
+++ b/org-tweetyproject-web/src/test/java/org/tweetyproject/web/services/RequestControllerBipolarTest.java
@@ -0,0 +1,202 @@
+/*
+ * 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.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 Oleksandr Dzhychko
+ */
+@SpringBootTest
+@AutoConfigureMockMvc
+class RequestControllerBipolarTest {
+ @Autowired
+ private MockMvc mvc;
+
+ @Test
+ public void getInfos() throws Exception {
+ var post = post("/bipolar").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,
+ "semantics": [
+ "cf",
+ "sa",
+ "cl",
+ "c-ad",
+ "d-ad",
+ "n-ad",
+ "n-co",
+ "n-gr",
+ "n-pr",
+ "n-st"
+ ],
+ "commands": [
+ "get_models",
+ "get_model"
+ ]
+ }
+ """, true));
+ }
+
+ @Test
+ public void getModels() throws Exception {
+ var post = post("/bipolar").contentType(MediaType.APPLICATION_JSON)
+ // language=JSON
+ .content("""
+ {
+ "cmd": "get_models",
+ "nr_of_arguments": 3,
+ "attacks": [[1, 2]],
+ "supports": [[2, 3]],
+ "semantics": "c-ad",
+ "timeout": 10,
+ "unit_timeout": "s"
+ }
+ """);
+
+ mvc.perform(post).andExpect(status().isOk())
+ // language=JSON
+ .andExpect(content().json("""
+ {
+ "reply": "get_models",
+ "email": null,
+ "nr_of_arguments": 3,
+ "attacks": [
+ [
+ 1,
+ 2
+ ]
+ ],
+ "supports": [
+ [
+ 2,
+ 3
+ ]
+ ],
+ "semantics": "c-ad",
+ "solver": null,
+ "answer": "[{1}, {3}, {1,3}, {2,3}]",
+ "time": 0.0,
+ "unit_time": "s",
+ "status": "SUCCESS"
+ }
+ """, true));
+ }
+
+ @Test
+ public void getModel() throws Exception {
+ var post = post("/bipolar").contentType(MediaType.APPLICATION_JSON)
+ // language=JSON
+ .content("""
+ {
+ "cmd": "get_model",
+ "nr_of_arguments": 3,
+ "attacks": [[1, 2]],
+ "supports": [[2, 3]],
+ "semantics": "c-ad",
+ "timeout": 10,
+ "unit_timeout": "s"
+ }
+ """);
+
+ mvc.perform(post).andExpect(status().isOk())
+ // language=JSON
+ .andExpect(content().json("""
+ {
+ "reply": "get_model",
+ "email": null,
+ "nr_of_arguments": 3,
+ "attacks": [
+ [
+ 1,
+ 2
+ ]
+ ],
+ "supports": [
+ [
+ 2,
+ 3
+ ]
+ ],
+ "semantics": "c-ad",
+ "solver": null,
+ "answer": "{1}",
+ "time": 0.0,
+ "unit_time": "s",
+ "status": "SUCCESS"
+ }
+ """, true));
+ }
+
+ private static Stream availableSemantics() {
+ return Stream.of(BipolarSemantics.values());
+ }
+
+ @ParameterizedTest(name = "semantics {0}")
+ @MethodSource("availableSemantics")
+ public void getModelsForSemantics(BipolarSemantics semantics) throws Exception {
+ var post = post("/bipolar").contentType(MediaType.APPLICATION_JSON)
+ // language=JSON
+ .content(String.format("""
+ {
+ "cmd": "get_models",
+ "nr_of_arguments": 3,
+ "attacks": [[1, 2]],
+ "supports": [[2, 3]],
+ "semantics": "%s",
+ "timeout": 10,
+ "unit_timeout": "s"
+ }
+ """, semantics.id));
+
+ mvc.perform(post).andExpect(status().isOk())
+ .andExpect(content().json("""
+ {
+ "status": "SUCCESS"
+ }
+ """));
+ }
+}
\ No newline at end of file