Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -426,6 +428,111 @@ public DungServicesInfoResponse getInfo(@RequestBody DungReasonerPost dungPost)
return response;
}

/**
* Handles HTTP POST requests for bipolar extension reasoner operations.
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>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.</p>
*
* <p>If the command is not recognized or not applicable, the method returns a default BipolarReasonerResponse.</p>
*
* @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<Collection<Extension<DungTheory>>> future = executor.submit(callee);
Pair<Collection<Extension<DungTheory>>, 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<String> semantics_ids = new ArrayList<String>();
for (var s : sem) {
semantics_ids.add(s.id);
}
response.setSemantics(semantics_ids);

BipolarReasonerCalleeFactory.Command[] com = BipolarReasonerCalleeFactory.getCommands();
ArrayList<String> command_ids = new ArrayList<String>();
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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

/**
Expand All @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
*
* Copyright 2026 The TweetyProject Team <http://tweetyproject.org/contact/>
*/
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<List<Integer>> attacks,
List<List<Integer>> supports) {
var argumentationFramework = switch (semantics.input) {
case DeductiveArgumentationFramework -> new DeductiveArgumentationFramework();
case NecessityArgumentationFramework -> new NecessityArgumentationFramework();
};

var arguments = new ArrayList<BArgument>();
for (int i = 1; i <= numberOfArguments; i++){
var argument = new BArgument(Integer.toString(i));
arguments.add(argument);
argumentationFramework.add(argument);
}

for (List<Integer> 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<Integer> 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;
}
}
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
*
* Copyright 2026 The TweetyProject Team <http://tweetyproject.org/contact/>
*/
package org.tweetyproject.web.services.bipolar;

/**
* @author Oleksandr Dzhychko
*/
public enum BipolarArgumentationFrameworkType {
DeductiveArgumentationFramework,
NecessityArgumentationFramework,
}
Loading
Loading