/*
* CompositionalRules.java
*
* Copyright (C) 2008 Pei Wang
*
* This file is part of Open-NARS.
*
* Open-NARS is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* Open-NARS is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the abduction warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Open-NARS. If not, see <http://www.gnu.org/licenses/>.
*/
package nars.inference;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import nars.storage.Memory;
import nars.entity.BudgetValue;
import nars.entity.Concept;
import nars.control.DerivationContext;
import nars.entity.Sentence;
import nars.entity.Task;
import nars.entity.TruthValue;
import static nars.inference.TruthFunctions.abduction;
import static nars.inference.TruthFunctions.comparison;
import static nars.inference.TruthFunctions.induction;
import static nars.inference.TruthFunctions.intersection;
import static nars.inference.TruthFunctions.negation;
import static nars.inference.TruthFunctions.reduceConjunction;
import static nars.inference.TruthFunctions.reduceConjunctionNeg;
import static nars.inference.TruthFunctions.reduceDisjunction;
import static nars.inference.TruthFunctions.union;
import nars.io.Symbols;
import nars.language.CompoundTerm;
import nars.language.Conjunction;
import nars.language.DifferenceExt;
import nars.language.DifferenceInt;
import nars.language.Disjunction;
import nars.language.Equivalence;
import nars.language.ImageExt;
import nars.language.ImageInt;
import nars.language.Implication;
import nars.language.Inheritance;
import nars.language.IntersectionExt;
import nars.language.IntersectionInt;
import nars.language.SetExt;
import nars.language.SetInt;
import nars.language.Similarity;
import nars.language.Statement;
import nars.language.Term;
import static nars.language.Terms.reduceComponents;
import nars.language.Variable;
import nars.language.Variables;
import static nars.inference.TruthFunctions.abduction;
import static nars.inference.TruthFunctions.abduction;
import static nars.inference.TruthFunctions.abduction;
/**
* Compound term composition and decomposition rules, with two premises.
* <p>
* New compound terms are introduced only in forward inference, while
* decompositional rules are also used in backward inference
*/
public final class CompositionalRules {
/* -------------------- intersections and differences -------------------- */
/**
* {<S ==> M>, <P ==> M>} |- {<(S|P) ==> M>, <(S&P) ==> M>, <(S-P) ==>
* M>,
* <(P-S) ==> M>}
*
* @param taskSentence The first premise
* @param belief The second premise
* @param index The location of the shared term
* @param nal Reference to the memory
*/
static void composeCompound(final Statement taskContent, final Statement beliefContent, final int index, final DerivationContext nal) {
if ((!nal.getCurrentTask().sentence.isJudgment()) || (taskContent.getClass() != beliefContent.getClass())) {
return;
}
final Term componentT = taskContent.term[1 - index];
final Term componentB = beliefContent.term[1 - index];
final Term componentCommon = taskContent.term[index];
int order1 = taskContent.getTemporalOrder();
int order2 = beliefContent.getTemporalOrder();
int order = TemporalRules.composeOrder(order1, order2);
if (order == TemporalRules.ORDER_INVALID) {
return;
}
if ((componentT instanceof CompoundTerm) && ((CompoundTerm) componentT).containsAllTermsOf(componentB)) {
decomposeCompound((CompoundTerm) componentT, componentB, componentCommon, index, true, order, nal);
return;
} else if ((componentB instanceof CompoundTerm) && ((CompoundTerm) componentB).containsAllTermsOf(componentT)) {
decomposeCompound((CompoundTerm) componentB, componentT, componentCommon, index, false, order, nal);
return;
}
final TruthValue truthT = nal.getCurrentTask().sentence.truth;
final TruthValue truthB = nal.getCurrentBelief().truth;
final TruthValue truthOr = union(truthT, truthB);
final TruthValue truthAnd = intersection(truthT, truthB);
TruthValue truthDif = null;
Term termOr = null;
Term termAnd = null;
Term termDif = null;
if (index == 0) {
if (taskContent instanceof Inheritance) {
termOr = IntersectionInt.make(componentT, componentB);
termAnd = IntersectionExt.make(componentT, componentB);
if (truthB.isNegative()) {
if (!truthT.isNegative()) {
termDif = DifferenceExt.make(componentT, componentB);
truthDif = intersection(truthT, negation(truthB));
}
} else if (truthT.isNegative()) {
termDif = DifferenceExt.make(componentB, componentT);
truthDif = intersection(truthB, negation(truthT));
}
} else if (taskContent instanceof Implication) {
termOr = Disjunction.make(componentT, componentB);
termAnd = Conjunction.make(componentT, componentB);
}
processComposed(taskContent, componentCommon, termOr, order, truthOr, nal);
processComposed(taskContent, componentCommon, termAnd, order, truthAnd, nal);
processComposed(taskContent, componentCommon, termDif, order, truthDif, nal);
} else { // index == 1
if (taskContent instanceof Inheritance) {
termOr = IntersectionExt.make(componentT, componentB);
termAnd = IntersectionInt.make(componentT, componentB);
if (truthB.isNegative()) {
if (!truthT.isNegative()) {
termDif = DifferenceInt.make(componentT, componentB);
truthDif = intersection(truthT, negation(truthB));
}
} else if (truthT.isNegative()) {
termDif = DifferenceInt.make(componentB, componentT);
truthDif = intersection(truthB, negation(truthT));
}
} else if (taskContent instanceof Implication) {
termOr = Conjunction.make(componentT, componentB);
termAnd = Disjunction.make(componentT, componentB);
}
processComposed(taskContent, termOr, componentCommon, order, truthOr, nal);
processComposed(taskContent, termAnd, componentCommon, order, truthAnd, nal);
processComposed(taskContent, termDif, componentCommon, order, truthDif, nal);
}
}
/**
* Finish composing implication term
*
* @param premise1 Type of the contentInd
* @param subject Subject of contentInd
* @param predicate Predicate of contentInd
* @param truth TruthValue of the contentInd
* @param memory Reference to the memory
*/
private static void processComposed(final Statement statement, final Term subject, final Term predicate, final int order, final TruthValue truth, final DerivationContext nal) {
if ((subject == null) || (predicate == null)) {
return;
}
Term content = Statement.make(statement, subject, predicate, order);
if ((content == null) || statement == null || content.equals(statement) || content.equals(nal.getCurrentBelief().term)) {
return;
}
BudgetValue budget = BudgetFunctions.compoundForward(truth, content, nal);
nal.doublePremiseTask(content, truth, budget, false, false); //(allow overlap) but not needed here, isn't detachment, this one would be even problematic from control perspective because its composition
}
/**
* {<(S|P) ==> M>, <P ==> M>} |- <S ==> M>
*
* @param implication The implication term to be decomposed
* @param componentCommon The part of the implication to be removed
* @param term1 The other term in the contentInd
* @param index The location of the shared term: 0 for subject, 1 for
* predicate
* @param compoundTask Whether the implication comes from the task
* @param nal Reference to the memory
*/
private static void decomposeCompound(CompoundTerm compound, Term component, Term term1, int index, boolean compoundTask, int order, DerivationContext nal) {
if ((compound instanceof Statement) || (compound instanceof ImageExt) || (compound instanceof ImageInt)) {
return;
}
Term term2 = reduceComponents(compound, component, nal.mem());
if (term2 == null) {
return;
}
Task task = nal.getCurrentTask();
Sentence sentence = task.sentence;
Sentence belief = nal.getCurrentBelief();
Statement oldContent = (Statement) task.getTerm();
TruthValue v1,
v2;
if (compoundTask) {
v1 = sentence.truth;
v2 = belief.truth;
} else {
v1 = belief.truth;
v2 = sentence.truth;
}
TruthValue truth = null;
Term content;
if (index == 0) {
content = Statement.make(oldContent, term1, term2, order);
if (content == null) {
return;
}
if (oldContent instanceof Inheritance) {
if (compound instanceof IntersectionExt) {
truth = reduceConjunction(v1, v2);
} else if (compound instanceof IntersectionInt) {
truth = reduceDisjunction(v1, v2);
} else if ((compound instanceof SetInt) && (component instanceof SetInt)) {
truth = reduceConjunction(v1, v2);
} else if ((compound instanceof SetExt) && (component instanceof SetExt)) {
truth = reduceDisjunction(v1, v2);
} else if (compound instanceof DifferenceExt) {
if (compound.term[0].equals(component)) {
truth = reduceDisjunction(v2, v1);
} else {
truth = reduceConjunctionNeg(v1, v2);
}
}
} else if (oldContent instanceof Implication) {
if (compound instanceof Conjunction) {
truth = reduceConjunction(v1, v2);
} else if (compound instanceof Disjunction) {
truth = reduceDisjunction(v1, v2);
}
}
} else {
content = Statement.make(oldContent, term2, term1, order);
if (content == null) {
return;
}
if (oldContent instanceof Inheritance) {
if (compound instanceof IntersectionInt) {
truth = reduceConjunction(v1, v2);
} else if (compound instanceof IntersectionExt) {
truth = reduceDisjunction(v1, v2);
} else if ((compound instanceof SetExt) && (component instanceof SetExt)) {
truth = reduceConjunction(v1, v2);
} else if ((compound instanceof SetInt) && (component instanceof SetInt)) {
truth = reduceDisjunction(v1, v2);
} else if (compound instanceof DifferenceInt) {
if (compound.term[1].equals(component)) {
truth = reduceDisjunction(v2, v1);
} else {
truth = reduceConjunctionNeg(v1, v2);
}
}
} else if (oldContent instanceof Implication) {
if (compound instanceof Disjunction) {
truth = reduceConjunction(v1, v2);
} else if (compound instanceof Conjunction) {
truth = reduceDisjunction(v1, v2);
}
}
}
if (truth != null) {
BudgetValue budget = BudgetFunctions.compoundForward(truth, content, nal);
nal.doublePremiseTask(content, truth, budget, false, true); //(allow overlap), a form of detachment
}
}
/**
* {(||, S, P), P} |- S {(&&, S, P), P} |- S
*
* @param implication The implication term to be decomposed
* @param componentCommon The part of the implication to be removed
* @param compoundTask Whether the implication comes from the task
* @param nal Reference to the memory
*/
static void decomposeStatement(CompoundTerm compound, Term component, boolean compoundTask, int index, DerivationContext nal) {
if ((compound instanceof Conjunction) && (compound.getTemporalOrder() == TemporalRules.ORDER_FORWARD) && (index != 0)) {
return;
}
Task task = nal.getCurrentTask();
Sentence taskSentence = task.sentence;
Sentence belief = nal.getCurrentBelief();
Term content = reduceComponents(compound, component, nal.mem());
if (content == null) {
return;
}
TruthValue truth = null;
BudgetValue budget;
if (taskSentence.isQuestion() || taskSentence.isQuest()) {
budget = BudgetFunctions.compoundBackward(content, nal);
nal.doublePremiseTask(content, truth, budget, false, false);
// special inference to answer conjunctive questions with query variables
if (taskSentence.term.hasVarQuery()) {
Concept contentConcept = nal.mem().concept(content);
if (contentConcept == null) {
return;
}
Sentence contentBelief = contentConcept.getBelief(nal, task);
if (contentBelief == null) {
return;
}
Task contentTask = new Task(contentBelief, task.budget);
nal.setCurrentTask(contentTask);
Term conj = Conjunction.make(component, content);
truth = intersection(contentBelief.truth, belief.truth);
budget = BudgetFunctions.compoundForward(truth, conj, nal);
nal.doublePremiseTask(conj, truth, budget, false, false);
}
} else {
TruthValue v1, v2;
if (compoundTask) {
v1 = taskSentence.truth;
v2 = belief.truth;
} else {
v1 = belief.truth;
v2 = taskSentence.truth;
}
if (compound instanceof Conjunction) {
if (taskSentence.isGoal()) {
if (compoundTask) {
truth = intersection(v1, v2);
} else {
return;
}
} else { // isJudgment
truth = reduceConjunction(v1, v2);
}
} else if (compound instanceof Disjunction) {
if (taskSentence.isGoal()) {
if (compoundTask) {
truth = reduceConjunction(v2, v1);
} else {
return;
}
} else { // isJudgment
truth = reduceDisjunction(v1, v2);
}
} else {
return;
}
budget = BudgetFunctions.compoundForward(truth, content, nal);
}
nal.doublePremiseTask(content, truth, budget, false, false);
}
/* till this general code is ready, the easier solution
public static void FindSame(Term a, Term b, HashMap<Term, Term> subs) {
if(b.containsTermRecursively(a)) {
}
}*/
/* --------------- rules used for variable introduction --------------- */
// forward inference only?
/**
* Introduce a dependent variable in an outer-layer conjunction {<S --> P1>,
* <S --> P2>} |- (&&, <#x --> P1>, <#x --> P2>)
*
* @param taskContent The first premise <M --> S>
* @param beliefContent The second premise <M --> P>
* @param index The location of the shared term: 0 for subject, 1 for
* predicate
* @param nal Reference to the memory
*/
public static void introVarOuter(final Statement taskContent, final Statement beliefContent, final int index, final DerivationContext nal) {
if (!(taskContent instanceof Inheritance)) {
return;
}
Variable varInd1 = new Variable("$varInd1");
Variable varInd2 = new Variable("$varInd2");
Term term11dependent=null, term12dependent=null, term21dependent=null, term22dependent=null;
Term term11, term12, term21, term22, commonTerm = null;
HashMap<Term, Term> subs = new HashMap<>();
if (index == 0) {
term11 = varInd1;
term21 = varInd1;
term12 = taskContent.getPredicate();
term22 = beliefContent.getPredicate();
term12dependent=term12;
term22dependent=term22;
if (term12 instanceof ImageExt) {
if ((/*(ImageExt)*/term12).containsTermRecursively(term22)) {
commonTerm = term22;
}
if(commonTerm == null && term12 instanceof ImageExt) {
commonTerm = ((ImageExt) term12).getTheOtherComponent();
if(!(term22.containsTermRecursively(commonTerm))) {
commonTerm=null;
}
if (term22 instanceof ImageExt && ((commonTerm == null) || !(term22).containsTermRecursively(commonTerm))) {
commonTerm = ((ImageExt) term22).getTheOtherComponent();
if ((commonTerm == null) || !(term12).containsTermRecursively(commonTerm)) {
commonTerm = null;
}
}
}
if (commonTerm != null) {
subs.put(commonTerm, varInd2);
term12 = ((CompoundTerm) term12).applySubstitute(subs);
if(!(term22 instanceof CompoundTerm)) {
term22 = varInd2;
} else {
term22 = ((CompoundTerm) term22).applySubstitute(subs);
}
}
}
if (commonTerm==null && term22 instanceof ImageExt) {
if ((/*(ImageExt)*/term22).containsTermRecursively(term12)) {
commonTerm = term12;
}
if(commonTerm == null && term22 instanceof ImageExt) {
commonTerm = ((ImageExt) term22).getTheOtherComponent();
if(!(term12.containsTermRecursively(commonTerm))) {
commonTerm=null;
}
if (term12 instanceof ImageExt && ((commonTerm == null) || !(term12).containsTermRecursively(commonTerm))) {
commonTerm = ((ImageExt) term12).getTheOtherComponent();
if ((commonTerm == null) || !(term22).containsTermRecursively(commonTerm)) {
commonTerm = null;
}
}
}
if (commonTerm != null) {
subs.put(commonTerm, varInd2);
term22 = ((CompoundTerm) term22).applySubstitute(subs);
if(!(term12 instanceof CompoundTerm)) {
term12 = varInd2;
} else {
term12 = ((CompoundTerm) term12).applySubstitute(subs);
}
}
}
} else {
term11 = taskContent.getSubject();
term21 = beliefContent.getSubject();
term12 = varInd1;
term22 = varInd1;
term11dependent=term11;
term21dependent=term21;
if (term21 instanceof ImageInt) {
if ((/*(ImageInt)*/term21).containsTermRecursively(term11)) {
commonTerm = term11;
}
if(term11 instanceof ImageInt && commonTerm == null && term21 instanceof ImageInt) {
commonTerm = ((ImageInt) term11).getTheOtherComponent();
if(!(term21.containsTermRecursively(commonTerm))) {
commonTerm=null;
}
if ((commonTerm == null) || !(term21).containsTermRecursively(commonTerm)) {
commonTerm = ((ImageInt) term21).getTheOtherComponent();
if ((commonTerm == null) || !(term11).containsTermRecursively(commonTerm)) {
commonTerm = null;
}
}
}
if (commonTerm != null) {
subs.put(commonTerm, varInd2);
term21 = ((CompoundTerm) term21).applySubstitute(subs);
if(!(term11 instanceof CompoundTerm)) {
term11 = varInd2;
} else {
term11 = ((CompoundTerm) term11).applySubstitute(subs);
}
}
}
if (commonTerm==null && term11 instanceof ImageInt) {
if ((/*(ImageInt)*/term11).containsTermRecursively(term21)) {
commonTerm = term21;
}
if(term21 instanceof ImageInt && commonTerm == null && term11 instanceof ImageInt) {
commonTerm = ((ImageInt) term21).getTheOtherComponent();
if(!(term11.containsTermRecursively(commonTerm))) {
commonTerm=null;
}
if ((commonTerm == null) || !(term11).containsTermRecursively(commonTerm)) {
commonTerm = ((ImageInt) term11).getTheOtherComponent();
if ((commonTerm == null) || !(term21).containsTermRecursively(commonTerm)) {
commonTerm = null;
}
}
}
if (commonTerm != null) {
subs.put(commonTerm, varInd2);
term11 = ((CompoundTerm) term11).applySubstitute(subs);
if(!(term21 instanceof CompoundTerm)) {
term21 = varInd2;
} else {
term21 = ((CompoundTerm) term21).applySubstitute(subs);
}
}
}
}
Statement state1 = Inheritance.make(term11, term12);
Statement state2 = Inheritance.make(term21, term22);
Term content = Implication.make(state1, state2);
if (content == null) {
return;
}
TruthValue truthT = nal.getCurrentTask().sentence.truth;
TruthValue truthB = nal.getCurrentBelief().truth;
/*
if (truthT == null)
throw new RuntimeException("CompositionalRules.introVarOuter: current task has null truth: " + memory.getCurrentTask());
if (truthB == null)
throw new RuntimeException("CompositionalRules.introVarOuter: current belief has null truth: " + memory.getCurrentBelief());
*/
if ((truthT == null) || (truthB == null)) {
return;
}
TruthValue truth = induction(truthT, truthB);
BudgetValue budget = BudgetFunctions.compoundForward(truth, content, nal);
nal.doublePremiseTask(content, truth, budget, false, false);
content = Implication.make(state2, state1);
truth = induction(truthB, truthT);
budget = BudgetFunctions.compoundForward(truth, content, nal);
nal.doublePremiseTask(content, truth, budget, false, false);
content = Equivalence.make(state1, state2);
truth = comparison(truthT, truthB);
budget = BudgetFunctions.compoundForward(truth, content, nal);
nal.doublePremiseTask(content, truth, budget, false, false);
Variable varDep = new Variable("#varDep");
if (index == 0) {
state1 = Inheritance.make(varDep, term12dependent);
state2 = Inheritance.make(varDep, term22dependent);
} else {
state1 = Inheritance.make(term11dependent, varDep);
state2 = Inheritance.make(term21dependent, varDep);
}
if ((state1==null) || (state2 == null))
return;
content = Conjunction.make(state1, state2);
truth = intersection(truthT, truthB);
budget = BudgetFunctions.compoundForward(truth, content, nal);
nal.doublePremiseTask(content, truth, budget, false, false);
}
/**
* {<M --> S>, <C ==> <M --> P>>} |- <(&&, <#x --> S>, C) ==> <#x --> P>>
* {<M --> S>, (&&, C, <M --> P>)} |- (&&, C, <<#x --> S> ==> <#x --> P>>)
*
* @param taskContent The first premise directly used in internal induction,
* <M --> S>
* @param beliefContent The componentCommon to be used as a premise in
* internal induction, <M --> P>
* @param oldCompound The whole contentInd of the first premise, Implication
* or Conjunction
* @param nal Reference to the memory
*/
static boolean introVarInner(Statement premise1, Statement premise2, CompoundTerm oldCompound, DerivationContext nal) {
Task task = nal.getCurrentTask();
Sentence taskSentence = task.sentence;
if (!taskSentence.isJudgment() || (premise1.getClass() != premise2.getClass()) || oldCompound.containsTerm(premise1)) {
return false;
}
Term subject1 = premise1.getSubject();
Term subject2 = premise2.getSubject();
Term predicate1 = premise1.getPredicate();
Term predicate2 = premise2.getPredicate();
Term commonTerm1, commonTerm2;
if (subject1.equals(subject2)) {
commonTerm1 = subject1;
commonTerm2 = secondCommonTerm(predicate1, predicate2, 0);
} else if (predicate1.equals(predicate2)) {
commonTerm1 = predicate1;
commonTerm2 = secondCommonTerm(subject1, subject2, 0);
} else {
return false;
}
Sentence belief = nal.getCurrentBelief();
HashMap<Term, Term> substitute = new HashMap<>();
boolean b1 = false, b2 = false;
{
Variable varDep2 = new Variable("#varDep2");
Term content = Conjunction.make(premise1, oldCompound);
if (!(content instanceof CompoundTerm))
return false;
substitute.put(commonTerm1, varDep2);
content = ((CompoundTerm)content).applySubstitute(substitute);
TruthValue truth = intersection(taskSentence.truth, belief.truth);
BudgetValue budget = BudgetFunctions.forward(truth, nal);
b1 = (nal.doublePremiseTask(content, truth, budget, false, false))!=null;
}
substitute.clear();
{
Variable varInd1 = new Variable("$varInd1");
Variable varInd2 = new Variable("$varInd2");
substitute.put(commonTerm1, varInd1);
if (commonTerm2 != null) {
substitute.put(commonTerm2, varInd2);
}
Term content = Implication.make(premise1, oldCompound);
if ((content == null) || (!(content instanceof CompoundTerm))) {
return false;
}
content = ((CompoundTerm)content).applySubstituteToCompound(substitute);
TruthValue truth;
if (premise1.equals(taskSentence.term)) {
truth = induction(belief.truth, taskSentence.truth);
} else {
truth = induction(taskSentence.truth, belief.truth);
}
BudgetValue budget = BudgetFunctions.forward(truth, nal);
b2 = nal.doublePremiseTask(content, truth, budget, false, false)!=null;
}
return b1 || b2;
}
/**
* Introduce a second independent variable into two terms with a common
* component
*
* @param term1 The first term
* @param term2 The second term
* @param index The index of the terms in their statement
*/
private static Term secondCommonTerm(Term term1, Term term2, int index) {
Term commonTerm = null;
if (index == 0) {
if ((term1 instanceof ImageExt) && (term2 instanceof ImageExt)) {
commonTerm = ((ImageExt) term1).getTheOtherComponent();
if ((commonTerm == null) || !term2.containsTermRecursively(commonTerm)) {
commonTerm = ((ImageExt) term2).getTheOtherComponent();
if ((commonTerm == null) || !term1.containsTermRecursively(commonTerm)) {
commonTerm = null;
}
}
}
} else if ((term1 instanceof ImageInt) && (term2 instanceof ImageInt)) {
commonTerm = ((ImageInt) term1).getTheOtherComponent();
if ((commonTerm == null) || !term2.containsTermRecursively(commonTerm)) {
commonTerm = ((ImageInt) term2).getTheOtherComponent();
if ((commonTerm == null) || !term1.containsTermRecursively(commonTerm)) {
commonTerm = null;
}
}
}
return commonTerm;
}
/*
The other inversion (abduction) should also be studied:
IN: <<lock1 --> (/,open,$1,_)> ==> <$1 --> key>>.
IN: <(&&,<#1 --> lock>,<#1 --> (/,open,$2,_)>) ==> <$2 --> key>>.
OUT: <lock1 --> lock>.
http://code.google.com/p/open-nars/issues/detail?id=40&can=1
*/
public static void eliminateVariableOfConditionAbductive(final int figure, final Sentence sentence, final Sentence belief, final DerivationContext nal) {
Statement T1 = (Statement) sentence.term;
Statement T2 = (Statement) belief.term;
Term S1 = T2.getSubject();
Term S2 = T1.getSubject();
Term P1 = T2.getPredicate();
Term P2 = T1.getPredicate();
HashMap<Term, Term> res1 = new HashMap<>();
HashMap<Term, Term> res2 = new HashMap<>();
HashMap<Term, Term> res3 = new HashMap<>();
HashMap<Term, Term> res4 = new HashMap<>();
if (figure == 21) {
res1.clear();
res2.clear();
Variables.findSubstitute(Symbols.VAR_INDEPENDENT, P1, S2, res1, res2); //this part is
T1 = (Statement) T1.applySubstitute(res2); //independent, the rule works if it unifies
if(T1==null) {
return;
}
T2 = (Statement) T2.applySubstitute(res1);
if(T2==null) {
return;
}
S1 = T2.getSubject();
S2 = T1.getSubject();
P1 = T2.getPredicate();
P2 = T1.getPredicate(); //update the variables because T1 and T2 may have changed
if (S1 instanceof Conjunction) {
//try to unify P2 with a component
for (final Term s1 : ((CompoundTerm) S1).term) {
res3.clear();
res4.clear(); //here the dependent part matters, see example of Issue40
if (Variables.findSubstitute(Symbols.VAR_DEPENDENT, s1, P2, res3, res4)) {
for (Term s2 : ((CompoundTerm) S1).term) {
if (!(s2 instanceof CompoundTerm)) {
continue;
}
s2 = ((CompoundTerm) s2).applySubstitute(res3);
if(s2==null || s2.hasVarIndep()) {
continue;
}
if (!s2.equals(s1) && (sentence.truth != null) && (belief.truth != null)) {
TruthValue truth = abduction(sentence.truth, belief.truth);
BudgetValue budget = BudgetFunctions.compoundForward(truth, s2, nal);
nal.doublePremiseTask(s2, truth, budget, false, false);
}
}
}
}
}
if (P2 instanceof Conjunction) {
//try to unify S1 with a component
for (final Term s1 : ((CompoundTerm) P2).term) {
res3.clear();
res4.clear(); //here the dependent part matters, see example of Issue40
if (Variables.findSubstitute(Symbols.VAR_DEPENDENT, s1, S1, res3, res4)) {
for (Term s2 : ((CompoundTerm) P2).term) {
if (!(s2 instanceof CompoundTerm)) {
continue;
}
s2 = ((CompoundTerm) s2).applySubstitute(res3);
if(s2==null || s2.hasVarIndep()) {
continue;
}
if (!s2.equals(s1) && (sentence.truth != null) && (belief.truth != null)) {
TruthValue truth = abduction(sentence.truth, belief.truth);
BudgetValue budget = BudgetFunctions.compoundForward(truth, s2, nal);
nal.doublePremiseTask(s2, truth, budget, false, false);
}
}
}
}
}
}
if (figure == 12) {
res1.clear();
res2.clear();
Variables.findSubstitute(Symbols.VAR_INDEPENDENT, S1, P2, res1, res2); //this part is
T1 = (Statement) T1.applySubstitute(res2); //independent, the rule works if it unifies
if(T1==null) {
return;
}
T2 = (Statement) T2.applySubstitute(res1);
if(T2==null) {
return;
}
S1 = T2.getSubject();
S2 = T1.getSubject();
P1 = T2.getPredicate();
P2 = T1.getPredicate(); //update the variables because T1 and T2 may have changed
if (S2 instanceof Conjunction) {
//try to unify P1 with a component
for (final Term s1 : ((CompoundTerm) S2).term) {
res3.clear();
res4.clear(); //here the dependent part matters, see example of Issue40
if (Variables.findSubstitute(Symbols.VAR_DEPENDENT, s1, P1, res3, res4)) {
for (Term s2 : ((CompoundTerm) S2).term) {
if (!(s2 instanceof CompoundTerm)) {
continue;
}
s2 = ((CompoundTerm) s2).applySubstitute(res3);
if(s2==null || s2.hasVarIndep()) {
continue;
}
if (!s2.equals(s1) && (sentence.truth != null) && (belief.truth != null)) {
TruthValue truth = abduction(sentence.truth, belief.truth);
BudgetValue budget = BudgetFunctions.compoundForward(truth, s2, nal);
nal.doublePremiseTask(s2, truth, budget, false, false);
}
}
}
}
}
if (P1 instanceof Conjunction) {
//try to unify S2 with a component
for (final Term s1 : ((CompoundTerm) P1).term) {
res3.clear();
res4.clear(); //here the dependent part matters, see example of Issue40
if (Variables.findSubstitute(Symbols.VAR_DEPENDENT, s1, S2, res3, res4)) {
for (Term s2 : ((CompoundTerm) P1).term) {
if (!(s2 instanceof CompoundTerm)) {
continue;
}
s2 = ((CompoundTerm) s2).applySubstitute(res3);
if(s2==null || s2.hasVarIndep()) {
continue;
}
if (!s2.equals(s1) && (sentence.truth != null) && (belief.truth != null)) {
TruthValue truth = abduction(sentence.truth, belief.truth);
BudgetValue budget = BudgetFunctions.compoundForward(truth, s2, nal);
nal.doublePremiseTask(s2, truth, budget, false, false);
}
}
}
}
}
}
if (figure == 11) {
res1.clear();
res2.clear();
Variables.findSubstitute(Symbols.VAR_INDEPENDENT, S1, S2, res1, res2); //this part is
T1 = (Statement) T1.applySubstitute(res2); //independent, the rule works if it unifies
if(T1==null) {
return;
}
T2 = (Statement) T2.applySubstitute(res1);
if(T2==null) {
return;
}
S1 = T2.getSubject();
S2 = T1.getSubject();
P1 = T2.getPredicate();
P2 = T1.getPredicate(); //update the variables because T1 and T2 may have changed
if (P1 instanceof Conjunction) {
//try to unify P2 with a component
for (final Term s1 : ((CompoundTerm) P1).term) {
res3.clear();
res4.clear(); //here the dependent part matters, see example of Issue40
if (Variables.findSubstitute(Symbols.VAR_DEPENDENT, s1, P2, res3, res4)) {
for (Term s2 : ((CompoundTerm) P1).term) {
if (!(s2 instanceof CompoundTerm)) {
continue;
}
s2 = ((CompoundTerm) s2).applySubstitute(res3);
if(s2==null || s2.hasVarIndep()) {
continue;
}
if ((!s2.equals(s1)) && (sentence.truth != null) && (belief.truth != null)) {
TruthValue truth = abduction(sentence.truth, belief.truth);
BudgetValue budget = BudgetFunctions.compoundForward(truth, s2, nal);
nal.doublePremiseTask(s2, truth, budget, false, false);
}
}
}
}
}
if (P2 instanceof Conjunction) {
//try to unify P1 with a component
for (final Term s1 : ((CompoundTerm) P2).term) {
res3.clear();
res4.clear(); //here the dependent part matters, see example of Issue40
if (Variables.findSubstitute(Symbols.VAR_DEPENDENT, s1, P1, res3, res4)) {
for (Term s2 : ((CompoundTerm) P2).term) {
if (!(s2 instanceof CompoundTerm)) {
continue;
}
s2 = ((CompoundTerm) s2).applySubstitute(res3);
if(s2==null || s2.hasVarIndep()) {
continue;
}
if (!s2.equals(s1) && (sentence.truth != null) && (belief.truth != null)) {
TruthValue truth = abduction(sentence.truth, belief.truth);
BudgetValue budget = BudgetFunctions.compoundForward(truth, s2, nal);
nal.doublePremiseTask(s2, truth, budget, false, false);
}
}
}
}
}
}
if (figure == 22) {
res1.clear();
res2.clear();
Variables.findSubstitute(Symbols.VAR_INDEPENDENT, P1, P2, res1, res2); //this part is
T1 = (Statement) T1.applySubstitute(res2); //independent, the rule works if it unifies
if(T1==null) {
return;
}
T2 = (Statement) T2.applySubstitute(res1);
if(T2==null) {
return;
}
S1 = T2.getSubject();
S2 = T1.getSubject();
P1 = T2.getPredicate();
P2 = T1.getPredicate(); //update the variables because T1 and T2 may have changed
if (S1 instanceof Conjunction) {
//try to unify S2 with a component
for (final Term s1 : ((CompoundTerm) S1).term) {
res3.clear();
res4.clear(); //here the dependent part matters, see example of Issue40
if (Variables.findSubstitute(Symbols.VAR_DEPENDENT, s1, S2, res3, res4)) {
for (Term s2 : ((CompoundTerm) S1).term) {
if (!(s2 instanceof CompoundTerm)) {
continue;
}
s2 = ((CompoundTerm) s2).applySubstitute(res3);
if(s2==null || s2.hasVarIndep()) {
continue;
}
if (s2!=null && !s2.equals(s1) && (sentence.truth != null) && (belief.truth != null)) {
TruthValue truth = abduction(sentence.truth, belief.truth);
BudgetValue budget = BudgetFunctions.compoundForward(truth, s2, nal);
nal.doublePremiseTask(s2, truth, budget, false, false);
}
}
}
}
}
if (S2 instanceof Conjunction) {
//try to unify S1 with a component
for (final Term s1 : ((CompoundTerm) S2).term) {
res3.clear();
res4.clear(); //here the dependent part matters, see example of Issue40
if (Variables.findSubstitute(Symbols.VAR_DEPENDENT, s1, S1, res3, res4)) {
for (Term s2 : ((CompoundTerm) S2).term) {
if (!(s2 instanceof CompoundTerm)) {
continue;
}
s2 = ((CompoundTerm) s2).applySubstitute(res3);
if(s2==null || s2.hasVarIndep()) {
continue;
}
if (s2!=null && !s2.equals(s1) && (sentence.truth != null) && (belief.truth != null)) {
TruthValue truth = abduction(sentence.truth, belief.truth);
BudgetValue budget = BudgetFunctions.compoundForward(truth, s2, nal);
nal.doublePremiseTask(s2, truth, budget, false, false);
}
}
}
}
}
}
}
static void IntroVarSameSubjectOrPredicate(final Sentence originalMainSentence, final Sentence subSentence, final Term component, final Term content, final int index, final DerivationContext nal) {
Term T1 = originalMainSentence.term;
if (!(T1 instanceof CompoundTerm) || !(content instanceof CompoundTerm)) {
return;
}
CompoundTerm T = (CompoundTerm) T1;
CompoundTerm T2 = (CompoundTerm) content;
if ((component instanceof Inheritance && content instanceof Inheritance)
|| (component instanceof Similarity && content instanceof Similarity)) {
//CompoundTerm result = T;
if (component.equals(content)) {
return; //wouldnt make sense to create a conjunction here, would contain a statement twice
}
Variable depIndVar1 = new Variable("#depIndVar1");
Variable depIndVar2 = new Variable("#depIndVar2");
if (((Statement) component).getPredicate().equals(((Statement) content).getPredicate()) && !(((Statement) component).getPredicate() instanceof Variable)) {
CompoundTerm zw = (CompoundTerm) T.term[index];
zw = (CompoundTerm) zw.setComponent(1, depIndVar1, nal.mem());
T2 = (CompoundTerm) T2.setComponent(1, depIndVar1, nal.mem());
Conjunction res = (Conjunction) Conjunction.make(zw, T2);
T = (CompoundTerm) T.setComponent(index, res, nal.mem());
} else if (((Statement) component).getSubject().equals(((Statement) content).getSubject()) && !(((Statement) component).getSubject() instanceof Variable)) {
CompoundTerm zw = (CompoundTerm) T.term[index];
zw = (CompoundTerm) zw.setComponent(0, depIndVar2, nal.mem());
T2 = (CompoundTerm) T2.setComponent(0, depIndVar2, nal.mem());
Conjunction res = (Conjunction) Conjunction.make(zw, T2);
T = (CompoundTerm) T.setComponent(index, res, nal.mem());
}
TruthValue truth = induction(originalMainSentence.truth, subSentence.truth);
BudgetValue budget = BudgetFunctions.compoundForward(truth, T, nal);
nal.doublePremiseTask(T, truth, budget, false, false);
}
}
}