All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.sf.tweety.arg.aspic.reasoner.DirectionalAspicReasoner Maven / Gradle / Ivy

There is a newer version: 1.17
Show newest version
/*
 *  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 2018 The TweetyProject Team 
 */
package net.sf.tweety.arg.aspic.reasoner;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.Set;

import net.sf.tweety.arg.aspic.ruleformulagenerator.RuleFormulaGenerator;
import net.sf.tweety.arg.aspic.semantics.AspicAttack;
import net.sf.tweety.arg.aspic.syntax.AspicArgument;
import net.sf.tweety.arg.aspic.syntax.AspicArgumentationTheory;
import net.sf.tweety.arg.aspic.syntax.DefeasibleInferenceRule;
import net.sf.tweety.arg.aspic.syntax.InferenceRule;
import net.sf.tweety.arg.dung.reasoner.AbstractExtensionReasoner;
import net.sf.tweety.arg.dung.syntax.Argument;
import net.sf.tweety.arg.dung.syntax.Attack;
import net.sf.tweety.arg.dung.syntax.DungTheory;
import net.sf.tweety.logics.commons.syntax.interfaces.Invertable;

/**
 * Computes a restricted AF by only considering relevant arguments to a query. An optional 
 * probability value for including only a certain subset of relevant arguments turns this
 * reasoner into an approximative reasoner
 *  
 * @author Tjitze Rienstra, Matthias Thimm
 *
 * @param  the type of formulas
 */
public class DirectionalAspicReasoner extends AbstractAspicReasoner {

	private double prob = 1.0d;
	
	/**
	 * Creates a new instance
	 * @param aafReasoner Underlying reasoner for AAFs. 
	 */
	public DirectionalAspicReasoner(AbstractExtensionReasoner aafReasoner) {
		this(aafReasoner,1d);
	}
	
	/**
	 * Creates a new instance
	 * @param aafReasoner Underlying reasoner for AAFs. 
	 * @param prob the probability of including a certain relevant argument
	 */
	public DirectionalAspicReasoner(AbstractExtensionReasoner aafReasoner, double prob) {
		super(aafReasoner);
		this.prob = prob;
	}
	
	/* (non-Javadoc)
	 * @see net.sf.tweety.arg.aspic.reasoner.AbstractAspicReasoner#getDungTheory(net.sf.tweety.arg.aspic.syntax.AspicArgumentationTheory, net.sf.tweety.logics.commons.syntax.interfaces.Invertable)
	 */
	@Override
	public DungTheory getDungTheory(AspicArgumentationTheory aat, T query) {
		return asRestrictedDungTheory(aat, false, query);
	}
	
	/**
	 * Generate restricted AF based on given theory and conclusion. 
	 * 
	 * The restricted AF contains only arguments with the given concusion, all the
	 * attackers of this argument, the attackers of those arguments, and so on.
	 * 
	 * As long as the semantics that is employed satisfies directionality, this 
	 * restricted AF is sufficient to determine the correct status of the conclusion.
	 * 
	 * @param aat The aspic theory to generate arguments from
	 * @param simplifyArgumentStructure @see net.sf.tweety.arg.aspic.AbstractAspicReasoner#getDungTheory(net.sf.tweety.arg.aspic.AspicArgumentationTheory, net.sf.tweety.commons.Formula)
	 * @param conc Conclusion to generate restricted AF for
	 * @return The restricted AF
	 */
	public DungTheory asRestrictedDungTheory(AspicArgumentationTheory aat, boolean simplifyArgumentStructure, T conc) {
		Collection> args = getArgsRec(aat, conc);
		DungTheory dung_theory = new DungTheory();
		dung_theory.addAll(args);
		dung_theory.addAllAttacks(AspicAttack.determineAttackRelations(args, aat.getOrder(), aat.getRuleFormulaGenerator()));
		if(!simplifyArgumentStructure)
			return dung_theory;
		DungTheory dung_theory2 = new DungTheory();
		Map old2new = new HashMap<>();
		int idx = 0;
		for(Argument a: dung_theory) {
			Argument b = new Argument("A"+idx++);
			old2new.put(a, b);
			dung_theory2.add(b);
		}
		for(Attack att: dung_theory.getAttacks()) {
			dung_theory2.add(new Attack(old2new.get(att.getAttacker()),old2new.get(att.getAttacked())));
		}		
		return dung_theory2;
	}

	private Set> constructArgsWithConclusion(AspicArgumentationTheory aat, T conc, Set conclusions) {
	
		conclusions = new HashSet(conclusions);
		conclusions.add(conc);

		Set> result = new LinkedHashSet>();
		outer: for (InferenceRule rule: aat.getRulesWithConclusion(conc)) {
			// Skip rules where conclusion is repeated as premise
			for (T premise: rule.getPremise()) {
				if (conclusions.contains(premise)) {
					continue outer;
				}
			}
			// Set up list of partial args (i.e. may not contain necessary sub args)
			Set> newPartialArgs = new LinkedHashSet>();
			Set> partialArgs = new LinkedHashSet>();
			partialArgs.add(new AspicArgument(rule));

			// For each premise ...
			for (T premise: rule.getPremise()) {
				// Construct all sub args
				Set> subArgs = constructArgsWithConclusion(aat, premise, conclusions);
				
				// Update and replace all partial args
				newPartialArgs.clear();
				for (AspicArgument partialArg: partialArgs) {
					for (AspicArgument subArg: subArgs) {
						AspicArgument partialArgCopy = partialArg.shallowCopy();
						partialArgCopy.addDirectSub(subArg);
						newPartialArgs.add(partialArgCopy);
					}
				}
				partialArgs.clear();
				partialArgs.addAll(newPartialArgs);
				newPartialArgs.clear();

			}
			result.addAll(partialArgs);
		}
		return result;
	}
	
	
	/**
	 * @return	arguments with given conclusion plus recursively all attackers 
	 */
	private Collection> getArgsRec(AspicArgumentationTheory aat, T conc) {
			
		
		Random r = new Random();
		
		Set> newArgs = new LinkedHashSet>();
		Set> args = new LinkedHashSet>();
		Set> argsDone = new HashSet>();
		Set conclusionsDone = new HashSet();

		args.addAll(constructArgsWithConclusion(aat, conc, new HashSet()));
		conclusionsDone.add(conc);
		
		boolean repeat = true;
		while (repeat) {
			repeat = false;
			newArgs.clear();
			for (AspicArgument argument: args) {
				if (argsDone.contains(argument)) continue;
				argsDone.add(argument);
				if (r.nextFloat() < prob) {
					for (T conclusion: getAttackingConclusions(argument, aat.getRuleFormulaGenerator())) {
						if (!conclusionsDone.contains(conclusion)) {
							conclusionsDone.add(conclusion);
							newArgs.addAll(constructArgsWithConclusion(aat, conclusion, new HashSet()));
						}
					}
				}
			}
			if (!newArgs.isEmpty()) {
				args.addAll(newArgs);
				repeat = true;
			}
		}
		
		return args;
	}
	
	/**
	 * Returns all "attacking conclusions" of the given argument.
	 * 
	 * An attacking conclusion of an argument is a conclusion that, if it is a conclusion of 
 	 * another argument, then this argument will attack it.
	 * 
	 * @param arg Argument to generate attacking conclusions
	 * @param rfgen Rule formula generator in use.
	 * @return Attacking conclusions of argument.
	 */
	@SuppressWarnings("unchecked")
	public Collection getAttackingConclusions(AspicArgument arg, RuleFormulaGenerator rfgen) {
		Collection cs = new ArrayList();
		Objects.requireNonNull(rfgen);
		// Add undercutters
		for (InferenceRule dr: arg.getDefeasibleRules()) {
			cs.add((T)rfgen.getRuleFormula((DefeasibleInferenceRule) dr).complement());
		}
		// Add rebutters
		for (AspicArgument a : arg.getDefeasibleSubs()) {
			cs.add((T)a.getTopRule().getConclusion().complement());
		}
		// Add underminers
		for (AspicArgument a : arg.getOrdinaryPremises()) {
			cs.add((T)a.getTopRule().getConclusion().complement());
		}
		return cs;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		return "dirRand-" + this.prob;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy