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

fr.boreal.forward_chaining.chase.ChaseBuilder Maven / Gradle / Ivy

The newest version!
package fr.boreal.forward_chaining.chase;

import fr.boreal.forward_chaining.chase.halting_condition.CreatedFactsAtPreviousStep;
import fr.boreal.forward_chaining.chase.halting_condition.HaltingCondition;
import fr.boreal.forward_chaining.chase.halting_condition.HasRulesToApply;
import fr.boreal.forward_chaining.chase.rule_applier.BreadthFirstTriggerRuleApplier;
import fr.boreal.forward_chaining.chase.rule_applier.ParallelTriggerRuleApplier;
import fr.boreal.forward_chaining.chase.rule_applier.RuleApplier;
import fr.boreal.forward_chaining.chase.rule_applier.SourceDelegatedDatalogRuleApplier;
import fr.boreal.forward_chaining.chase.rule_applier.body_to_query_transformer.AllTransformer;
import fr.boreal.forward_chaining.chase.rule_applier.body_to_query_transformer.BodyToQueryTransformer;
import fr.boreal.forward_chaining.chase.rule_applier.body_to_query_transformer.FrontierTransformer;
import fr.boreal.forward_chaining.chase.rule_applier.trigger_applier.TriggerApplier;
import fr.boreal.forward_chaining.chase.rule_applier.trigger_applier.TriggerApplierImpl;
import fr.boreal.forward_chaining.chase.rule_applier.trigger_applier.facts_handler.DelegatedApplication;
import fr.boreal.forward_chaining.chase.rule_applier.trigger_applier.facts_handler.DirectApplication;
import fr.boreal.forward_chaining.chase.rule_applier.trigger_applier.facts_handler.FactsHandler;
import fr.boreal.forward_chaining.chase.rule_applier.trigger_applier.renamer.*;
import fr.boreal.forward_chaining.chase.rule_applier.trigger_checker.*;
import fr.boreal.forward_chaining.chase.rule_applier.trigger_computer.NaiveTriggerComputer;
import fr.boreal.forward_chaining.chase.rule_applier.trigger_computer.SemiNaiveComputer;
import fr.boreal.forward_chaining.chase.rule_applier.trigger_computer.TriggerComputer;
import fr.boreal.forward_chaining.chase.rule_applier.trigger_computer.TwoStepComputer;
import fr.boreal.forward_chaining.chase.rule_scheduler.GRDScheduler;
import fr.boreal.forward_chaining.chase.rule_scheduler.NaiveScheduler;
import fr.boreal.forward_chaining.chase.rule_scheduler.RuleScheduler;
import fr.boreal.forward_chaining.chase.treatment.AddCreatedFacts;
import fr.boreal.forward_chaining.chase.treatment.Debug;
import fr.boreal.forward_chaining.chase.treatment.EndTreatment;
import fr.boreal.forward_chaining.chase.treatment.Pretreatment;
import fr.boreal.model.formula.api.FOFormula;
import fr.boreal.model.kb.api.FactBase;
import fr.boreal.model.kb.api.RuleBase;
import fr.boreal.model.logicalElements.factory.api.TermFactory;
import fr.boreal.model.logicalElements.factory.impl.FactoryConstants;
import fr.boreal.model.queryEvaluation.api.FOQueryEvaluator;
import fr.boreal.query_evaluation.generic.FOQueryEvaluatorWithDBMSDelegation;
import fr.boreal.query_evaluation.generic.GenericFOQueryEvaluator;

import java.util.*;

/**
 * @author Florent Tornil
 *
 * Builder to create a parameterized chase algorithm
 */
public class ChaseBuilder {

	private FactBase fb;
	private RuleBase rb;
	private TermFactory tf = FactoryConstants.DEFAULT_TERM_FACTORY;

	private RuleScheduler rsc;
	private Scheduler scheduler = Scheduler.GRD;
	private enum Scheduler {NAIVE, GRD}

	private FOQueryEvaluator eval;
	private Evaluator evaluator = Evaluator.GENERIC;
	private enum Evaluator {GENERIC, SMART}

	private RuleApplier ra;
	private Applier applier = Applier.BREADTH_FIRST_TRIGGER;
	private enum Applier {BREADTH_FIRST_TRIGGER, PARALLEL_TRIGGER, SOURCE_DELEGATED_DATALOG}

	private BodyToQueryTransformer transf;
	private Transformer transformer = Transformer.FRONTIER;
	private enum Transformer {ALL, FRONTIER}

	private TriggerComputer tc;
	private Computer computer = Computer.SEMI_NAIVE;
	private enum Computer {NAIVE, SEMI_NAIVE, TWO_STEP}
	private TriggerChecker tch;
	private Checker checker = Checker.SEMI_OBLIVIOUS;
	private enum Checker {TRUE, OBLIVIOUS, SEMI_OBLIVIOUS, RESTRICTED, EQUIVALENT}
	private TriggerApplier ta;
	private FactsHandler fh;
	private Application application = Application.DIRECT;
	private enum Application {DIRECT, PARALLEL}
	private TriggerRenamer renamer;
	private Skolem skolem = Skolem.FRESH;
	private enum Skolem {FRESH, BODY, FRONTIER, FRONTIER_PIECE}


	private final List hcs = new ArrayList<>();
	private final List global_pts = new ArrayList<>();
	private final List step_pts = new ArrayList<>();
	private final List global_end_ts = new ArrayList<>();
	private final List end_step_ts = new ArrayList<>();

	private boolean debug = false;

	///////////
	// Build //
	///////////

	/**
	 * The minimal configuration requires : 
* * a FactBase to saturate
* * a RuleBase to get Rules from
* * a TermFactory to create new terms
*
* Default behavior is :
* * a GRDScheduler for rules
* * a TriggerRuleApplier with :
* * * a SemiNaiveTriggerComputer with a default GenericFOQueryEvaluator
* * * a SemiObliviousChecker
* * * a Applier with :
* * * * a FreshRenamer
* * * * a DirectApplication
* * HaltingConditions :
* * * CreatedFactsAtPreviousStep
* * * HasRulesToApply
* * @return the created chase or an empty optional if the configuration is incorrect */ public Optional build() { if(this.getMinimalConfig().isPresent()) { return Optional.of(new ChaseImpl(fb, rb, rsc, ra, hcs, global_pts, step_pts, global_end_ts, end_step_ts)); } else { return Optional.empty(); } } //////////////////// // Default chases // //////////////////// /** * Builder initialized with the default chase and mandatory parameters * @param fb the factbase to saturate * @param rb the rule to apply * @return the builder initialized with the given parameters */ public static ChaseBuilder defaultBuilder(FactBase fb, RuleBase rb) { return new ChaseBuilder() .setFactBase(fb) .setRuleBase(rb); } /** * Chase initialized with the default parameters and the given mandatory parameters * @param fb the factbase to saturate * @param rb the rule to apply * @return the default chase initialized with the given parameters */ public static Chase defaultChase(FactBase fb, RuleBase rb) { return new ChaseBuilder() .setFactBase(fb) .setRuleBase(rb) .build() .get(); } ////////////////////// // Default settings // ////////////////////// private Optional getMinimalConfig() { if(this.fb == null) { return Optional.empty(); } if(this.rb == null) { return Optional.empty(); } if(this.tf == null) { return Optional.empty(); } if(this.rsc == null) { switch (this.scheduler) { case NAIVE : this.setRuleScheduler(new NaiveScheduler(this.rb)); break; case GRD : this.setRuleScheduler(new GRDScheduler(this.rb)); break; } } if(this.eval == null) { switch (this.evaluator) { case GENERIC : this.setFOQueryEvaluator(GenericFOQueryEvaluator.defaultInstance()); break; case SMART : this.setFOQueryEvaluator(FOQueryEvaluatorWithDBMSDelegation.defaultInstance()); break; } } if(this.ra == null) { switch(this.applier) { case BREADTH_FIRST_TRIGGER : case PARALLEL_TRIGGER : { if(this.transf == null) { switch (this.transformer) { case ALL : this.setBodyToQueryTransformer(new AllTransformer()); break; case FRONTIER : this.setBodyToQueryTransformer(new FrontierTransformer()); break; } } if(this.tc == null) { switch (this.computer) { case NAIVE : this.setTriggerComputer(new NaiveTriggerComputer(this.eval)); break; case SEMI_NAIVE : this.setTriggerComputer(new SemiNaiveComputer(this.eval)); break; case TWO_STEP : this.setTriggerComputer(new TwoStepComputer(this.eval)); break; } } if(this.tch == null) { switch (this.checker) { case TRUE : this.setTriggerChecker(new AlwaysTrueChecker()); break; case OBLIVIOUS : this.setTriggerChecker(new ObliviousChecker()); break; case SEMI_OBLIVIOUS : this.setTriggerChecker(new SemiObliviousChecker()); break; case RESTRICTED : this.setTriggerChecker(new RestrictedChecker(this.eval)); break; case EQUIVALENT : this.setTriggerChecker(new EquivalentChecker(this.eval)); break; } } if(this.ta == null) { if(this.renamer == null) { switch (this.skolem) { case FRESH : this.setExistentialsRenamer(new FreshRenamer(this.tf)); break; case BODY : this.setExistentialsRenamer(new BodySkolem(this.tf)); break; case FRONTIER : this.setExistentialsRenamer(new FrontierSkolem(this.tf)); break; case FRONTIER_PIECE : this.setExistentialsRenamer(new FrontierByPieceSkolem(this.tf)); break; } } if(this.fh == null) { switch(this.application) { case DIRECT : this.setNewFactsHandler(new DirectApplication()); break; case PARALLEL : this.setNewFactsHandler(new DelegatedApplication()); break; } } this.setTriggerApplier(new TriggerApplierImpl(this.renamer, this.fh)); } break; } case SOURCE_DELEGATED_DATALOG: // do nothing break; } switch(this.applier) { case BREADTH_FIRST_TRIGGER : this.setRuleApplier(new BreadthFirstTriggerRuleApplier(this.transf, this.tc, this.tch, this.ta)); break; case PARALLEL_TRIGGER : this.setRuleApplier(new ParallelTriggerRuleApplier(this.transf, this.tc, this.tch, this.ta)); break; case SOURCE_DELEGATED_DATALOG : this.setRuleApplier(new SourceDelegatedDatalogRuleApplier()); break; } } if(this.hcs.isEmpty()) { this.addStandardHaltingConditions(); } if(this.application == Application.PARALLEL) { this.end_step_ts.addFirst(new AddCreatedFacts()); } if(this.debug) { this.addStepEndTreatments(new Debug()); } return Optional.of(this); } /////////////////////////// // Higher level settings // /////////////////////////// // Rule Applier // /** * Use a breadth first trigger applier * @return this */ public ChaseBuilder useTriggerRuleApplier() { this.applier = Applier.BREADTH_FIRST_TRIGGER; return this; } // FOQuery Evaluator // /** * Use the generic query evaluator * @return this */ public ChaseBuilder useGenericFOQueryEvaluator() { this.evaluator = Evaluator.GENERIC; return this; } /** * Use the smart query evaluator * @return this */ public ChaseBuilder useSmartFOQueryEvaluator() { this.evaluator = Evaluator.SMART; return this; } // Scheduler // /** * Use a naive rule scheduler * @return this */ public ChaseBuilder useNaiveRuleScheduler() { this.scheduler = Scheduler.NAIVE; return this; } /** * Use a rule scheduler based on the GRD * @return this */ public ChaseBuilder useGRDRuleScheduler() { this.scheduler = Scheduler.GRD; return this; } // Body To Query transformers // /** * Use a transformation that keep all variables as answer variables when evaluating a rule's body * @return this */ public ChaseBuilder useAllTransformer() { this.transformer = Transformer.ALL; return this; } /** * Use a transformation that keep only the variables of the frontier as answer variables when evaluating a rule's body * @return this */ public ChaseBuilder useFrontierTransformer() { this.transformer = Transformer.FRONTIER; return this; } // Computer // /** * Use a naive method to compute triggers * @return this */ public ChaseBuilder useNaiveComputer() { this.computer = Computer.NAIVE; return this; } /** * Use the semi naive method to compute triggers * @return this */ public ChaseBuilder useSemiNaiveComputer() { this.computer = Computer.SEMI_NAIVE; return this; } /** * Use the two step method to compute triggers * @return this */ public ChaseBuilder useTwoStepComputer() { this.computer = Computer.TWO_STEP; return this; } // Application // /** * Use a direct application of the triggers * @return this */ public ChaseBuilder useDirectApplication() { this.application = Application.DIRECT; this.applier = Applier.BREADTH_FIRST_TRIGGER; return this; } /** * Use a parallel application of the triggers * @return this */ public ChaseBuilder useParallelApplication() { this.application = Application.PARALLEL; this.applier = Applier.PARALLEL_TRIGGER; return this; } /** * Use a method of delegating to the source the application of the datalog rules * @return this */ public ChaseBuilder useSourceDelegatedDatalogApplication() { this.applier = Applier.SOURCE_DELEGATED_DATALOG; return this; } // Criteria // /** * Use an always true criteria for the triggers * @return this */ public ChaseBuilder useAlwaysTrueChecker() { this.checker = Checker.TRUE; return this; } /** * Use a oblivious criteria for the triggers * @return this */ public ChaseBuilder useObliviousChecker() { this.checker = Checker.OBLIVIOUS; return this; } /** * Use a semi oblivious criteria for the triggers * @return this */ public ChaseBuilder useSemiObliviousChecker() { this.checker = Checker.SEMI_OBLIVIOUS; return this; } /** * Use a restricted criteria for the triggers * @return this */ public ChaseBuilder useRestrictedChecker() { this.checker = Checker.RESTRICTED; return this; } /** * Use an equivalent criteria for the triggers * @return this */ public ChaseBuilder useEquivalentChecker() { this.checker = Checker.EQUIVALENT; return this; } // Existentials naming // /** * Use a fresh name for the existentials * @return this */ public ChaseBuilder useFreshNaming() { this.skolem = Skolem.FRESH; return this; } /** * Use a skolem of the body as name for the existentials * @return this */ public ChaseBuilder useBodySkolem() { this.skolem = Skolem.BODY; return this; } /** * Use a skolem of the body, limited to the frontier as name for the existentials * @return this */ public ChaseBuilder useFrontierSkolem() { this.skolem = Skolem.FRONTIER; return this; } /** * Use a skolem of the body, limited to the frontier of the piece as name for the existentials * @return this */ public ChaseBuilder useFrontierByPieceSkolem() { this.skolem = Skolem.FRONTIER_PIECE; return this; } ///////////// // Setters // ///////////// /** * Sets the FactBase * @param fb the FactBase * @return this */ public ChaseBuilder setFactBase(FactBase fb) { this.fb = fb; return this; } /** * Sets the RuleBase * @param rb the RuleBase * @return this */ public ChaseBuilder setRuleBase(RuleBase rb) { this.rb = rb; return this; } /** * Sets the TermFactory * @param tf the TermFactory * @return this */ public ChaseBuilder setTermFactory(TermFactory tf) { this.tf = tf; return this; } /** * Sets the RuleScheduler * @param rsc the RuleScheduler * @return this */ public ChaseBuilder setRuleScheduler(RuleScheduler rsc) { this.rsc = rsc; return this; } /** * Sets the FOQueryEvaluator * @param eval the FOQueryEvaluator * @return this */ public ChaseBuilder setFOQueryEvaluator(FOQueryEvaluator eval) { this.eval = eval; return this; } /** * Sets the RuleApplier * @param ra the RuleApplier * @return this */ public ChaseBuilder setRuleApplier(RuleApplier ra) { this.ra = ra; return this; } // Triggers /** * Sets the BodyToQueryTransformer * @param transf the BodyToQueryTransformer * @return this */ public ChaseBuilder setBodyToQueryTransformer(BodyToQueryTransformer transf) { this.transf = transf; return this; } /** * Sets the TriggerComputer * @param tc the TriggerComputer * @return this */ public ChaseBuilder setTriggerComputer(TriggerComputer tc) { this.tc = tc; return this; } /** * Sets the TriggerChecker * @param tch the TriggerChecker * @return this */ public ChaseBuilder setTriggerChecker(TriggerChecker tch) { this.tch = tch; return this; } /** * Sets the TriggerApplier * @param ta the TriggerApplier * @return this */ public ChaseBuilder setTriggerApplier(TriggerApplier ta) { this.ta = ta; return this; } /** * Sets the TriggerRenamer * @param tr the TriggerRenamer * @return this */ public ChaseBuilder setExistentialsRenamer(TriggerRenamer tr) { this.renamer = tr; return this; } /** * Sets the FactsHandler * @param fh the FactsHandler * @return this */ public ChaseBuilder setNewFactsHandler(FactsHandler fh) { this.fh = fh; return this; } // halting conditions /** * Adds the standard halting conditions * @return this */ public ChaseBuilder addStandardHaltingConditions() { this.addHaltingConditions(new CreatedFactsAtPreviousStep(), new HasRulesToApply()); return this; } /** * Adds the given halting conditions * @param hcs halting conditions * @return this */ public ChaseBuilder addHaltingConditions(HaltingCondition... hcs) { this.hcs.addAll(Arrays.asList(hcs)); return this; } /** * Adds the given halting conditions * @param hcs halting conditions * @return this */ public ChaseBuilder addHaltingConditions(Collection hcs) { this.hcs.addAll(hcs); return this; } // Global pretreatment /** * Adds the given Global pretreatment * @param pts Global pretreatment * @return this */ public ChaseBuilder addGlobalPretreatments(Pretreatment... pts) { this.global_pts.addAll(Arrays.asList(pts)); return this; } /** * Adds the given Global pretreatment * @param pts Global pretreatment * @return this */ public ChaseBuilder addGlobalPretreatments(Collection pts) { this.global_pts.addAll(pts); return this; } // Step pretreament /** * Adds the given Step pretreatment * @param pts Step pretreatment * @return this */ public ChaseBuilder addStepPretreatments(Pretreatment... pts) { this.step_pts.addAll(Arrays.asList(pts)); return this; } /** * Adds the given Step pretreatment * @param pts Step pretreatment * @return this */ public ChaseBuilder addStepPretreatments(Collection pts) { this.step_pts.addAll(pts); return this; } // Global end treatement /** * Adds the given Global end treatement * @param ets Step Global end treatement * @return this */ public ChaseBuilder addGlobalEndTreatments(EndTreatment... ets) { this.global_end_ts.addAll(Arrays.asList(ets)); return this; } /** * Adds the given Global end treatement * @param ets Step Global end treatement * @return this */ public ChaseBuilder addGlobalEndTreatments(Collection ets) { this.global_end_ts.addAll(ets); return this; } // Step end treatement /** * Adds the given Step end treatement * @param ets Step end treatement * @return this */ public ChaseBuilder addStepEndTreatments(EndTreatment... ets) { this.end_step_ts.addAll(Arrays.asList(ets)); return this; } /** * Adds the given Step end treatement * @param ets Step end treatement * @return this */ public ChaseBuilder addStepEndTreatments(Collection ets) { this.end_step_ts.addAll(ets); return this; } /** * Adds the debug option * @return this */ public ChaseBuilder debug() { this.debug = true; return this; } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy