/*
* RuleTables.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 implied 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.HashSet;
import nars.util.Events;
import nars.storage.Memory;
import nars.config.Parameters;
import nars.control.DerivationContext;
import nars.entity.BudgetValue;
import nars.entity.Concept;
import nars.entity.Sentence;
import nars.entity.Stamp;
import nars.entity.TLink;
import nars.entity.Task;
import nars.entity.TaskLink;
import nars.entity.TermLink;
import nars.entity.TruthValue;
import nars.io.Symbols;
import static nars.io.Symbols.VAR_DEPENDENT;
import static nars.io.Symbols.VAR_INDEPENDENT;
import static nars.io.Symbols.VAR_QUERY;
import nars.language.CompoundTerm;
import nars.language.Conjunction;
import nars.language.Disjunction;
import nars.language.Equivalence;
import nars.language.Implication;
import nars.language.Inheritance;
import nars.language.Negation;
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.equalSubTermsInRespectToImageAndProduct;
import nars.language.Variable;
import nars.language.Variables;
import nars.operator.Operation;
/**
* Table of inference rules, indexed by the TermLinks for the task and the
* belief. Used in indirective processing of a task, to dispatch inference cases
* to the relevant inference rules.
*/
public class RuleTables {
/**
* Entry point of the inference engine
*
* @param tLink The selected TaskLink, which will provide a task
* @param bLink The selected TermLink, which may provide a belief
* @param memory Reference to the memory
*/
public static void reason(final TaskLink tLink, final TermLink bLink, final DerivationContext nal) {
final Memory memory = nal.mem();
memory.emotion.manageBusy(nal);
final Task task = nal.getCurrentTask();
final Sentence taskSentence = task.sentence;
final Term taskTerm = taskSentence.term; // cloning for substitution
Term beliefTerm = bLink.target; // cloning for substitution
if(equalSubTermsInRespectToImageAndProduct(taskTerm,beliefTerm))
return;
final Concept beliefConcept = memory.concept(beliefTerm);
Sentence belief = (beliefConcept != null) ? beliefConcept.getBelief(nal, task) : null;
nal.setCurrentBelief( belief );
if (belief != null) {
beliefTerm = belief.term; //because interval handling that differs on conceptual level
/*Sentence belief_event = beliefConcept.getBeliefForTemporalInference(task);
if(belief_event != null) {
boolean found_overlap = false;
if(Stamp.baseOverlap(task.sentence.stamp.evidentialBase, belief_event.stamp.evidentialBase)) {
found_overlap = true;
}
if(!found_overlap) { //temporal rules are inductive so no chance to succeed if there is an overlap
//and since the temporal rule is relatively expensive the check here was good.
Sentence inference_belief = belief;
nal.setCurrentBelief(belief_event);
nal.setTheNewStamp(task.sentence.stamp, belief_event.stamp, nal.memory.time());
TemporalRules.temporalInduction(task.sentence, belief_event, nal, true);
nal.setCurrentBelief(inference_belief);
nal.setTheNewStamp(task.sentence.stamp, belief.stamp, nal.memory.time());
}
}*/
//too restrictive, its checked for non-deductive inference rules in derivedTask (also for single prem)
if(Stamp.baseOverlap(task.sentence.stamp.evidentialBase, belief.stamp.evidentialBase)) {
nal.evidentalOverlap = true;
if(!task.sentence.isEternal() || !belief.isEternal()) {
return; //only allow for eternal reasoning for now to prevent derived event floods
}
//return; //preparisons are made now to support this nicely
}
//comment out for recursive examples, this is for the future, it generates a lot of potentially useless tasks
nal.emit(Events.BeliefReason.class, belief, beliefTerm, taskTerm, nal);
if (LocalRules.match(task, belief, nal)) { //new tasks resulted from the match, so return
return;
}
}
//current belief and task may have changed, so set again:
nal.setCurrentBelief(belief);
nal.setCurrentTask(task);
/*if ((memory.getNewTaskCount() > 0) && taskSentence.isJudgment()) {
return;
}*/
final short tIndex = tLink.getIndex(0);
short bIndex = bLink.getIndex(0);
switch (tLink.type) { // dispatch first by TaskLink type
case TermLink.SELF:
switch (bLink.type) {
case TermLink.COMPONENT:
compoundAndSelf((CompoundTerm) taskTerm, beliefTerm, true, bIndex, nal);
break;
case TermLink.COMPOUND:
compoundAndSelf((CompoundTerm) beliefTerm, taskTerm, false, bIndex, nal);
break;
case TermLink.COMPONENT_STATEMENT:
if (belief != null) {
if (taskTerm instanceof Statement) {
SyllogisticRules.detachment(taskSentence, belief, bIndex, nal);
}
} //else {
try {
goalFromQuestion(task, taskTerm, nal);
}catch(Exception ex) {} //todo fix
//}
break;
case TermLink.COMPOUND_STATEMENT:
if (belief != null) {
SyllogisticRules.detachment(belief, taskSentence, bIndex, nal);
}
break;
case TermLink.COMPONENT_CONDITION:
if ((belief != null) && (taskTerm instanceof Implication)) {
bIndex = bLink.getIndex(1);
SyllogisticRules.conditionalDedInd(task.sentence,(Implication) taskTerm, bIndex, beliefTerm, tIndex, nal);
}
break;
case TermLink.COMPOUND_CONDITION:
if ((belief != null) && (taskTerm instanceof Implication) && (beliefTerm instanceof Implication)) {
bIndex = bLink.getIndex(1);
SyllogisticRules.conditionalDedInd(belief,(Implication) beliefTerm, bIndex, taskTerm, tIndex, nal);
}
break;
}
break;
case TermLink.COMPOUND:
switch (bLink.type) {
case TermLink.COMPOUND:
compoundAndCompound((CompoundTerm) taskTerm, (CompoundTerm) beliefTerm, bIndex, nal);
break;
case TermLink.COMPOUND_STATEMENT:
compoundAndStatement((CompoundTerm) taskTerm, tIndex, (Statement) beliefTerm, bIndex, beliefTerm, nal);
break;
case TermLink.COMPOUND_CONDITION:
if (belief != null) {
if (beliefTerm instanceof Implication) {
Term[] u = new Term[] { beliefTerm, taskTerm };
if (Variables.unify(VAR_INDEPENDENT, ((Statement) beliefTerm).getSubject(), taskTerm, u)) {
Sentence newBelief = belief.clone(u[0]);
Sentence newTaskSentence = taskSentence.clone(u[1]);
detachmentWithVar(newBelief, newTaskSentence, bIndex, nal);
} else {
SyllogisticRules.conditionalDedInd(belief, (Implication) beliefTerm, bIndex, taskTerm, -1, nal);
}
} else if (beliefTerm instanceof Equivalence) {
SyllogisticRules.conditionalAna((Equivalence) beliefTerm, bIndex, taskTerm, -1, nal);
}
}
break;
}
break;
case TermLink.COMPOUND_STATEMENT:
switch (bLink.type) {
case TermLink.COMPONENT:
if (taskTerm instanceof Statement) {
componentAndStatement((CompoundTerm) nal.getCurrentTerm(), bIndex, (Statement) taskTerm, tIndex, nal);
}
break;
case TermLink.COMPOUND:
if (taskTerm instanceof Statement) {
compoundAndStatement((CompoundTerm) beliefTerm, bIndex, (Statement) taskTerm, tIndex, beliefTerm, nal);
}
break;
case TermLink.COMPOUND_STATEMENT:
if (belief != null) {
syllogisms(tLink, bLink, taskTerm, beliefTerm, nal);
}
break;
case TermLink.COMPOUND_CONDITION:
if (belief != null) {
bIndex = bLink.getIndex(1);
if ((taskTerm instanceof Statement) && (beliefTerm instanceof Implication)) {
conditionalDedIndWithVar(belief, (Implication) beliefTerm, bIndex, (Statement) taskTerm, tIndex, nal);
}
}
break;
}
break;
case TermLink.COMPOUND_CONDITION:
switch (bLink.type) {
case TermLink.COMPOUND:
if (belief != null) {
detachmentWithVar(taskSentence, belief, tIndex, nal);
}
break;
case TermLink.COMPOUND_STATEMENT:
if (belief != null) {
if (taskTerm instanceof Implication) // TODO maybe put instanceof test within conditionalDedIndWithVar()
{
Term subj = ((Statement) taskTerm).getSubject();
if (subj instanceof Negation) {
if (taskSentence.isJudgment()) {
componentAndStatement((CompoundTerm) subj, bIndex, (Statement) taskTerm, tIndex, nal);
} else {
componentAndStatement((CompoundTerm) subj, tIndex, (Statement) beliefTerm, bIndex, nal);
}
} else {
conditionalDedIndWithVar(task.sentence, (Implication) taskTerm, tIndex, (Statement) beliefTerm, bIndex, nal);
}
}
break;
}
break;
}
}
}
private static void goalFromQuestion(final Task task, final Term taskTerm, final DerivationContext nal) {
if(task.sentence.punctuation==Symbols.QUESTION_MARK && (taskTerm instanceof Implication || taskTerm instanceof Equivalence)) { //<a =/> b>? |- a!
Term goalterm=null;
Term goalterm2=null;
if(taskTerm instanceof Implication) {
Implication imp=(Implication)taskTerm;
if(imp.getTemporalOrder()!=TemporalRules.ORDER_BACKWARD || imp.getTemporalOrder()==TemporalRules.ORDER_CONCURRENT) {
if(!Parameters.CURIOSITY_FOR_OPERATOR_ONLY || imp.getSubject() instanceof Operation) {
goalterm=imp.getSubject();
}
if(goalterm instanceof Variable && goalterm.hasVarQuery() && (!Parameters.CURIOSITY_FOR_OPERATOR_ONLY || imp.getPredicate() instanceof Operation)) {
goalterm=imp.getPredicate(); //overwrite, it is a how question, in case of <?how =/> b> it is b! which is desired
}
}
else
if(imp.getTemporalOrder()==TemporalRules.ORDER_BACKWARD) {
if(!Parameters.CURIOSITY_FOR_OPERATOR_ONLY || imp.getPredicate() instanceof Operation) {
goalterm=imp.getPredicate();
}
if(goalterm instanceof Variable && goalterm.hasVarQuery() && (!Parameters.CURIOSITY_FOR_OPERATOR_ONLY || imp.getSubject() instanceof Operation)) {
goalterm=imp.getSubject(); //overwrite, it is a how question, in case of <?how =/> b> it is b! which is desired
}
}
}
else
if(taskTerm instanceof Equivalence) {
Equivalence qu=(Equivalence)taskTerm;
if(qu.getTemporalOrder()==TemporalRules.ORDER_FORWARD || qu.getTemporalOrder()==TemporalRules.ORDER_CONCURRENT) {
if(!Parameters.CURIOSITY_FOR_OPERATOR_ONLY || qu.getSubject() instanceof Operation) {
goalterm=qu.getSubject();
}
if(!Parameters.CURIOSITY_FOR_OPERATOR_ONLY || qu.getPredicate() instanceof Operation) {
goalterm2=qu.getPredicate();
}
}
}
TruthValue truth=new TruthValue(1.0f,Parameters.DEFAULT_GOAL_CONFIDENCE*Parameters.CURIOSITY_DESIRE_CONFIDENCE_MUL);
if(goalterm!=null && !(goalterm instanceof Variable) && goalterm instanceof CompoundTerm) {
goalterm=((CompoundTerm)goalterm).transformIndependentVariableToDependentVar((CompoundTerm) goalterm);
Sentence sent=new Sentence(goalterm,Symbols.GOAL_MARK,truth,new Stamp(task.sentence.stamp,nal.memory.time()));
nal.singlePremiseTask(sent, new BudgetValue(task.getPriority()*Parameters.CURIOSITY_DESIRE_PRIORITY_MUL,task.getDurability()*Parameters.CURIOSITY_DESIRE_DURABILITY_MUL,BudgetFunctions.truthToQuality(truth)));
}
if(goalterm2!=null && !(goalterm2 instanceof Variable) && goalterm2 instanceof CompoundTerm) {
goalterm2=((CompoundTerm)goalterm).transformIndependentVariableToDependentVar((CompoundTerm) goalterm2);
Sentence sent=new Sentence(goalterm2,Symbols.GOAL_MARK,truth.clone(),new Stamp(task.sentence.stamp,nal.memory.time()));
nal.singlePremiseTask(sent, new BudgetValue(task.getPriority()*Parameters.CURIOSITY_DESIRE_PRIORITY_MUL,task.getDurability()*Parameters.CURIOSITY_DESIRE_DURABILITY_MUL,BudgetFunctions.truthToQuality(truth)));
}
}
}
/* ----- syllogistic inferences ----- */
/**
* Meta-table of syllogistic rules, indexed by the content classes of the
* taskSentence and the belief
*
* @param tLink The link to task
* @param bLink The link to belief
* @param taskTerm The content of task
* @param beliefTerm The content of belief
* @param nal Reference to the memory
*/
private static void syllogisms(TaskLink tLink, TermLink bLink, Term taskTerm, Term beliefTerm, DerivationContext nal) {
Sentence taskSentence = nal.getCurrentTask().sentence;
Sentence belief = nal.getCurrentBelief();
int figure;
if (taskTerm instanceof Inheritance) {
if (beliefTerm instanceof Inheritance) {
figure = indexToFigure(tLink, bLink);
asymmetricAsymmetric(taskSentence, belief, figure, nal);
} else if (beliefTerm instanceof Similarity) {
figure = indexToFigure(tLink, bLink);
asymmetricSymmetric(taskSentence, belief, figure, nal);
} else {
detachmentWithVar(belief, taskSentence, bLink.getIndex(0), nal);
}
} else if (taskTerm instanceof Similarity) {
if (beliefTerm instanceof Inheritance) {
figure = indexToFigure(bLink, tLink);
asymmetricSymmetric(belief, taskSentence, figure, nal);
} else if (beliefTerm instanceof Similarity) {
figure = indexToFigure(bLink, tLink);
symmetricSymmetric(belief, taskSentence, figure, nal);
} else if (beliefTerm instanceof Implication) {
//Bridge to higher order statements:
figure = indexToFigure(tLink, bLink);
asymmetricSymmetric(belief, taskSentence, figure, nal);
} else if (beliefTerm instanceof Equivalence) {
//Bridge to higher order statements:
figure = indexToFigure(tLink, bLink);
symmetricSymmetric(belief, taskSentence, figure, nal);
}
} else if (taskTerm instanceof Implication) {
if (beliefTerm instanceof Implication) {
figure = indexToFigure(tLink, bLink);
asymmetricAsymmetric(taskSentence, belief, figure, nal);
} else if (beliefTerm instanceof Equivalence) {
figure = indexToFigure(tLink, bLink);
asymmetricSymmetric(taskSentence, belief, figure, nal);
} else if (beliefTerm instanceof Inheritance) {
detachmentWithVar(taskSentence, belief, tLink.getIndex(0), nal);
} else if (beliefTerm instanceof Similarity) {
//Bridge to higher order statements:
figure = indexToFigure(tLink, bLink);
asymmetricSymmetric(taskSentence, belief, figure, nal);
}
} else if (taskTerm instanceof Equivalence) {
if (beliefTerm instanceof Implication) {
figure = indexToFigure(bLink, tLink);
asymmetricSymmetric(belief, taskSentence, figure, nal);
} else if (beliefTerm instanceof Equivalence) {
figure = indexToFigure(bLink, tLink);
symmetricSymmetric(belief, taskSentence, figure, nal);
} else if (beliefTerm instanceof Inheritance) {
detachmentWithVar(taskSentence, belief, tLink.getIndex(0), nal);
} else if (beliefTerm instanceof Similarity) {
//Bridge to higher order statements:
figure = indexToFigure(tLink, bLink);
symmetricSymmetric(belief, taskSentence, figure, nal);
}
}
}
/**
* Decide the figure of syllogism according to the locations of the common
* term in the premises
*
* @param link1 The link to the first premise
* @param link2 The link to the second premise
* @return The figure of the syllogism, one of the four: 11, 12, 21, or 22
*/
private static final int indexToFigure(final TLink link1, final TLink link2) {
return (link1.getIndex(0) + 1) * 10 + (link2.getIndex(0) + 1);
}
/**
* Syllogistic rules whose both premises are on the same asymmetric relation
*
* @param taskSentence The taskSentence in the task
* @param belief The judgment in the belief
* @param figure The location of the shared term
* @param nal Reference to the memory
*/
private static void asymmetricAsymmetric(final Sentence taskSentence, final Sentence belief, int figure, final DerivationContext nal) {
Statement taskStatement = (Statement) taskSentence.term;
Statement beliefStatement = (Statement) belief.term;
Term t1, t2;
Term[] u = new Term[] { taskStatement, beliefStatement };
switch (figure) {
case 11: // induction
if (Variables.unify(VAR_INDEPENDENT, taskStatement.getSubject(), beliefStatement.getSubject(), u)) {
taskStatement = (Statement) u[0];
beliefStatement = (Statement) u[1];
if (taskStatement.equals(beliefStatement)) {
return;
}
t1 = beliefStatement.getPredicate();
t2 = taskStatement.getPredicate();
SyllogisticRules.abdIndCom(t1, t2, taskSentence, belief, figure, nal);
CompositionalRules.composeCompound(taskStatement, beliefStatement, 0, nal);
//if(taskSentence.getOccurenceTime()==Stamp.ETERNAL && belief.getOccurenceTime()==Stamp.ETERNAL)
CompositionalRules.introVarOuter(taskStatement, beliefStatement, 0, nal);//introVarImage(taskContent, beliefContent, index, memory);
CompositionalRules.eliminateVariableOfConditionAbductive(figure,taskSentence,belief,nal);
}
break;
case 12: // deduction
if (Variables.unify(VAR_INDEPENDENT, taskStatement.getSubject(), beliefStatement.getPredicate(), u)) {
taskStatement = (Statement) u[0];
beliefStatement = (Statement) u[1];
if (taskStatement.equals(beliefStatement)) {
return;
}
t1 = beliefStatement.getSubject();
t2 = taskStatement.getPredicate();
if (Variables.unify(VAR_QUERY, t1, t2, new Term[] { taskStatement, beliefStatement })) {
LocalRules.matchReverse(nal);
} else {
SyllogisticRules.dedExe(t1, t2, taskSentence, belief, nal);
}
}
break;
case 21: // exemplification
if (Variables.unify(VAR_INDEPENDENT, taskStatement.getPredicate(), beliefStatement.getSubject(), u)) {
taskStatement = (Statement) u[0];
beliefStatement = (Statement) u[1];
if (taskStatement.equals(beliefStatement)) {
return;
}
t1 = taskStatement.getSubject();
t2 = beliefStatement.getPredicate();
if (Variables.unify(VAR_QUERY, t1, t2, new Term[] { taskStatement, beliefStatement })) {
LocalRules.matchReverse(nal);
} else {
SyllogisticRules.dedExe(t1, t2, taskSentence, belief, nal);
}
}
break;
case 22: // abduction
if (Variables.unify(VAR_INDEPENDENT, taskStatement.getPredicate(), beliefStatement.getPredicate(), u)) {
taskStatement = (Statement) u[0];
beliefStatement = (Statement) u[1];
if (taskStatement.equals(beliefStatement)) {
return;
}
t1 = taskStatement.getSubject();
t2 = beliefStatement.getSubject();
if (!SyllogisticRules.conditionalAbd(t1, t2, taskStatement, beliefStatement, nal)) { // if conditional abduction, skip the following
SyllogisticRules.abdIndCom(t1, t2, taskSentence, belief, figure, nal);
CompositionalRules.composeCompound(taskStatement, beliefStatement, 1, nal);
CompositionalRules.introVarOuter(taskStatement, beliefStatement, 1, nal);// introVarImage(taskContent, beliefContent, index, memory);
}
CompositionalRules.eliminateVariableOfConditionAbductive(figure,taskSentence,belief,nal);
}
break;
default:
}
}
/**
* Syllogistic rules whose first premise is on an asymmetric relation, and
* the second on a symmetric relation
*
* @param asym The asymmetric premise
* @param sym The symmetric premise
* @param figure The location of the shared term
* @param nal Reference to the memory
*/
private static void asymmetricSymmetric(final Sentence asym, final Sentence sym, final int figure, final DerivationContext nal) {
Statement asymSt = (Statement) asym.term;
Statement symSt = (Statement) sym.term;
Term t1, t2;
Term[] u = new Term[] { asymSt, symSt };
switch (figure) {
case 11:
if (Variables.unify(VAR_INDEPENDENT, asymSt.getSubject(), symSt.getSubject(), u)) {
asymSt = (Statement) u[0];
symSt = (Statement) u[1];
t1 = asymSt.getPredicate();
t2 = symSt.getPredicate();
if (Variables.unify(VAR_QUERY, t1, t2, u)) {
LocalRules.matchAsymSym(asym, sym, figure, nal);
} else {
SyllogisticRules.analogy(t2, t1, asym, sym, figure, nal);
}
}
break;
case 12:
if (Variables.unify(VAR_INDEPENDENT, asymSt.getSubject(), symSt.getPredicate(), u)) {
asymSt = (Statement) u[0];
symSt = (Statement) u[1];
t1 = asymSt.getPredicate();
t2 = symSt.getSubject();
if (Variables.unify(VAR_QUERY, t1, t2, u)) {
LocalRules.matchAsymSym(asym, sym, figure, nal);
} else {
SyllogisticRules.analogy(t2, t1, asym, sym, figure, nal);
}
}
break;
case 21:
if (Variables.unify(VAR_INDEPENDENT, asymSt.getPredicate(), symSt.getSubject(), u)) {
asymSt = (Statement) u[0];
symSt = (Statement) u[1];
t1 = asymSt.getSubject();
t2 = symSt.getPredicate();
if (Variables.unify(VAR_QUERY, t1, t2, u)) {
LocalRules.matchAsymSym(asym, sym, figure, nal);
} else {
SyllogisticRules.analogy(t1, t2, asym, sym, figure, nal);
}
}
break;
case 22:
if (Variables.unify(VAR_INDEPENDENT, asymSt.getPredicate(), symSt.getPredicate(), u)) {
asymSt = (Statement) u[0];
symSt = (Statement) u[1];
t1 = asymSt.getSubject();
t2 = symSt.getSubject();
if (Variables.unify(VAR_QUERY, t1, t2, u)) {
LocalRules.matchAsymSym(asym, sym, figure, nal);
} else {
SyllogisticRules.analogy(t1, t2, asym, sym, figure, nal);
}
}
break;
}
}
/**
* Syllogistic rules whose both premises are on the same symmetric relation
*
* @param belief The premise that comes from a belief
* @param taskSentence The premise that comes from a task
* @param figure The location of the shared term
* @param nal Reference to the memory
*/
private static void symmetricSymmetric(final Sentence belief, final Sentence taskSentence, int figure, final DerivationContext nal) {
Statement s1 = (Statement) belief.term;
Statement s2 = (Statement) taskSentence.term;
Term ut1, ut2; //parameters for unify()
Term rt1, rt2; //parameters for resemblance()
switch (figure) {
case 11:
ut1 = s1.getSubject();
ut2 = s2.getSubject();
rt1 = s1.getPredicate();
rt2 = s2.getPredicate();
break;
case 12:
ut1 = s1.getSubject();
ut2 = s2.getPredicate();
rt1 = s1.getPredicate();
rt2 = s2.getSubject();
break;
case 21:
ut1 = s1.getPredicate();
ut2 = s2.getSubject();
rt1 = s1.getSubject();
rt2 = s2.getPredicate();
break;
case 22:
ut1 = s1.getPredicate();
ut2 = s2.getPredicate();
rt1 = s1.getSubject();
rt2 = s2.getSubject();
break;
default:
throw new RuntimeException("Invalid figure: " + figure);
}
Term[] u = new Term[] { s1, s2 };
if (Variables.unify(VAR_INDEPENDENT, ut1, ut2, u)) {
//recalculate rt1, rt2 from above:
switch (figure) {
case 11: rt1 = s1.getPredicate(); rt2 = s2.getPredicate(); break;
case 12: rt1 = s1.getPredicate(); rt2 = s2.getSubject(); break;
case 21: rt1 = s1.getSubject(); rt2 = s2.getPredicate(); break;
case 22: rt1 = s1.getSubject(); rt2 = s2.getSubject(); break;
}
SyllogisticRules.resemblance(rt1, rt2, belief, taskSentence, figure, nal);
CompositionalRules.eliminateVariableOfConditionAbductive(
figure, taskSentence, belief, nal);
}
}
/* ----- conditional inferences ----- */
/**
* The detachment rule, with variable unification
*
* @param originalMainSentence The premise that is an Implication or
* Equivalence
* @param subSentence The premise that is the subject or predicate of the
* first one
* @param index The location of the second premise in the first
* @param nal Reference to the memory
*/
private static void detachmentWithVar(Sentence originalMainSentence, Sentence subSentence, int index, DerivationContext nal) {
if(originalMainSentence==null) {
return;
}
Sentence mainSentence = originalMainSentence; // for substitution
if (!(mainSentence.term instanceof Statement))
return;
Statement statement = (Statement) mainSentence.term;
Term component = statement.term[index];
Term content = subSentence.term;
if (((component instanceof Inheritance) || (component instanceof Negation)) && (nal.getCurrentBelief() != null)) {
Term[] u = new Term[] { statement, content };
if (!component.hasVarIndep() && !component.hasVarDep()) { //because of example: <<(*,w1,#2) --> [good]> ==> <w1 --> TRANSLATE>>. <(*,w1,w2) --> [good]>.
SyllogisticRules.detachment(mainSentence, subSentence, index, nal);
} else if (Variables.unify(VAR_INDEPENDENT, component, content, u)) {
mainSentence = mainSentence.clone(u[0]);
subSentence = subSentence.clone(u[1]);
SyllogisticRules.detachment(mainSentence, subSentence, index, nal);
} else if ((statement instanceof Implication) && (statement.getPredicate() instanceof Statement) && (nal.getCurrentTask().sentence.isJudgment())) {
Statement s2 = (Statement) statement.getPredicate();
if ((content instanceof Statement) && (s2.getSubject().equals(((Statement) content).getSubject()))) {
CompositionalRules.introVarInner((Statement) content, s2, statement, nal);
}
CompositionalRules.IntroVarSameSubjectOrPredicate(originalMainSentence,subSentence,component,content,index,nal);
} else if ((statement instanceof Equivalence) && (statement.getPredicate() instanceof Statement) && (nal.getCurrentTask().sentence.isJudgment())) {
CompositionalRules.IntroVarSameSubjectOrPredicate(originalMainSentence,subSentence,component,content,index,nal);
}
}
}
/**
* Conditional deduction or induction, with variable unification
*
* @param conditional The premise that is an Implication with a Conjunction
* as condition
* @param index The location of the shared term in the condition
* @param statement The second premise that is a statement
* @param side The location of the shared term in the statement
* @param nal Reference to the memory
*/
private static void conditionalDedIndWithVar(Sentence conditionalSentence, Implication conditional, short index, Statement statement, short side, DerivationContext nal) {
if (!(conditional.getSubject() instanceof CompoundTerm))
return;
CompoundTerm condition = (CompoundTerm) conditional.getSubject();
Term component = condition.term[index];
Term component2 = null;
if (statement instanceof Inheritance) {
component2 = statement;
side = -1;
} else if (statement instanceof Implication) {
component2 = statement.term[side];
}
if (component2 != null) {
Term[] u = new Term[] { conditional, statement };
boolean unifiable = Variables.unify(VAR_INDEPENDENT, component, component2, u);
if (!unifiable) {
unifiable = Variables.unify(VAR_DEPENDENT, component, component2, u);
}
if (unifiable) {
conditional = (Implication) u[0];
statement = (Statement) u[1];
SyllogisticRules.conditionalDedInd(conditionalSentence, conditional, index, statement, side, nal);
}
}
}
/* ----- structural inferences ----- */
/**
* Inference between a compound term and a component of it
*
* @param compound The compound term
* @param component The component term
* @param compoundTask Whether the compound comes from the task
* @param nal Reference to the memory
*/
private static void compoundAndSelf(CompoundTerm compound, Term component, boolean compoundTask, int index, DerivationContext nal) {
if ((compound instanceof Conjunction) || (compound instanceof Disjunction)) {
if (nal.getCurrentBelief() != null) {
CompositionalRules.decomposeStatement(compound, component, compoundTask, index, nal);
} else if (compound.containsTerm(component)) {
StructuralRules.structuralCompound(compound, component, compoundTask, index, nal);
}
// } else if ((compound instanceof Negation) && !memory.getCurrentTask().isStructural()) {
} else if (compound instanceof Negation) {
if (compoundTask) {
if (compound.term[0] instanceof CompoundTerm)
StructuralRules.transformNegation((CompoundTerm)compound.term[0], nal);
} else {
StructuralRules.transformNegation(compound, nal);
}
}
}
/**
* Inference between two compound terms
*
* @param taskTerm The compound from the task
* @param beliefTerm The compound from the belief
* @param nal Reference to the memory
*/
private static void compoundAndCompound(CompoundTerm taskTerm, CompoundTerm beliefTerm, int index, DerivationContext nal) {
if (taskTerm.getClass() == beliefTerm.getClass()) {
if (taskTerm.size() >= beliefTerm.size()) {
compoundAndSelf(taskTerm, beliefTerm, true, index, nal);
} else if (taskTerm.size() < beliefTerm.size()) {
compoundAndSelf(beliefTerm, taskTerm, false, index, nal);
}
}
}
/**
* Inference between a compound term and a statement
*
* @param compound The compound term
* @param index The location of the current term in the compound
* @param statement The statement
* @param side The location of the current term in the statement
* @param beliefTerm The content of the belief
* @param nal Reference to the memory
*/
private static void compoundAndStatement(CompoundTerm compound, short index, Statement statement, short side, Term beliefTerm, DerivationContext nal) {
if(index >= compound.term.length) {
return;
}
Term component = compound.term[index];
Task task = nal.getCurrentTask();
if (component.getClass() == statement.getClass()) {
if ((compound instanceof Conjunction) && (nal.getCurrentBelief() != null)) {
Term[] u = new Term[] { compound, statement };
if (Variables.unify(VAR_DEPENDENT, component, statement, u)) {
compound = (CompoundTerm) u[0];
statement = (Statement) u[1];
SyllogisticRules.elimiVarDep(compound, component,
statement.equals(beliefTerm),
nal);
} else if (task.sentence.isJudgment()) { // && !compound.containsTerm(component)) {
CompositionalRules.introVarInner(statement, (Statement) component, compound, nal);
} else if (Variables.unify(VAR_QUERY, component, statement, u)) {
compound = (CompoundTerm) u[0];
statement = (Statement) u[1];
CompositionalRules.decomposeStatement(compound, component, true, index, nal);
}
}
} else {
if (task.sentence.isJudgment()) {
if (statement instanceof Inheritance) {
StructuralRules.structuralCompose1(compound, index, statement, nal);
if (!(compound instanceof SetExt || compound instanceof SetInt || compound instanceof Negation)) {
StructuralRules.structuralCompose2(compound, index, statement, side, nal);
} // {A --> B, A @ (A&C)} |- (A&C) --> (B&C)
} else if ((statement instanceof Similarity) && !(compound instanceof Conjunction)) {
StructuralRules.structuralCompose2(compound, index, statement, side, nal);
} // {A <-> B, A @ (A&C)} |- (A&C) <-> (B&C)
}
}
}
/**
* Inference between a component term (of the current term) and a statement
*
* @param compound The compound term
* @param index The location of the current term in the compound
* @param statement The statement
* @param side The location of the current term in the statement
* @param nal Reference to the memory
*/
private static void componentAndStatement(CompoundTerm compound, short index, Statement statement, short side, DerivationContext nal) {
if (statement instanceof Inheritance) {
StructuralRules.structuralDecompose1(compound, index, statement, nal);
if (!(compound instanceof SetExt) && !(compound instanceof SetInt)) {
StructuralRules.structuralDecompose2(statement, index, nal); // {(C-B) --> (C-A), A @ (C-A)} |- A --> B
} else {
StructuralRules.transformSetRelation(compound, statement, side, nal);
}
} else if (statement instanceof Similarity) {
StructuralRules.structuralDecompose2(statement, index, nal); // {(C-B) --> (C-A), A @ (C-A)} |- A --> B
if ((compound instanceof SetExt) || (compound instanceof SetInt)) {
StructuralRules.transformSetRelation(compound, statement, side, nal);
}
}
/* else if ((statement instanceof Implication) && (compound instanceof Negation)) {
if (index == 0) {
StructuralRules.contraposition(statement, nal.getCurrentTask().sentence, nal);
} else {
StructuralRules.contraposition(statement, nal.getCurrentBelief(), nal);
}
}*/
}
/* ----- inference with one TaskLink only ----- */
/**
* The TaskLink is of type TRANSFORM, and the conclusion is an equivalent
* transformation
*
* @param tLink The task link
* @param nal Reference to the memory
*/
public static void transformTask(TaskLink tLink, DerivationContext nal) {
CompoundTerm content = (CompoundTerm) nal.getCurrentTask().getTerm();
short[] indices = tLink.index;
Term inh = null;
if ((indices.length == 2) || (content instanceof Inheritance)) { // <(*, term, #) --> #>
inh = content;
} else if (indices.length == 3) { // <<(*, term, #) --> #> ==> #>
inh = content.term[indices[0]];
} else if (indices.length == 4) { // <(&&, <(*, term, #) --> #>, #) ==> #>
Term component = content.term[indices[0]];
if ((component instanceof Conjunction) && (((content instanceof Implication) && (indices[0] == 0)) || (content instanceof Equivalence))) {
Term[] cterms = ((CompoundTerm) component).term;
if (indices[1] < cterms.length-1)
inh = cterms[indices[1]];
else
return;
} else {
return;
}
}
if (inh instanceof Inheritance) {
StructuralRules.transformProductImage((Inheritance) inh, content, indices, nal);
}
}
}