static ClassicalSentence makeJudgement(TermOrCompoundTermOrVariableReferer term, TruthValue truth) { ClassicalSentence result = new ClassicalSentence(EnumPunctation.JUDGMENT); result.term = term; result.truth = truth; return(result); }
/** * Constructor to make actual TermLink from a template * <p> * called in Concept.buildTermLinks only * @param t Target Term * @param template TermLink template previously prepared * @param v Budget value of the link */ private ClassicalTermLink(TermOrCompoundTermOrVariableReferer target, ClassicalTermLink template, ClassicalBudgetValue budget) : base(budget) { this.target = target; type = (template.target == target) ? (template.type - 1) //// point to component : template.type; index = template.index; // OpenNARS hash = init(); }
public static TemporaryDerivedCompoundType <Type> makeLeaf(TermOrCompoundTermOrVariableReferer termReferer) { TemporaryDerivedCompoundType <Type> result = new TemporaryDerivedCompoundType <Type>(); result.decoration = Activator.CreateInstance <Type>(); result.protectedTermReferer = termReferer; result.type = EnumType.LEAF; return(result); }
/** * Link to a new task from all relevant concepts for continued processing in * the near future for unspecified time. * <p> * The only method that calls the TaskLink constructor. * * /param task The task to be linked * /param content The content of the task */ private static void linkToTask(DerivationContext ctx, ClassicalConcept @this, ClassicalTask task) { ClassicalBudgetValue taskBudget = task.budget; @this.insertTaskLink( new ClassicalTaskLink( task, null, taskBudget, Parameters.TERM_LINK_RECORD_LENGTH), ctx); // link type: SELF if (!TermUtilities.isTermCompoundTerm(@this.term)) { return; } if (@this.termLinkTemplates.isEmpty()) { return; } ClassicalBudgetValue subBudget = BudgetFunctions.distributeAmongLinks(taskBudget, @this.termLinkTemplates.Count); if (!subBudget.isAboveThreshold) { return; } // else here for (int t = 0; t < @this.termLinkTemplates.Count; t++) { ClassicalTermLink termLink = @this.termLinkTemplates[t]; if (termLink.type == ClassicalTermLink.EnumType.TEMPORAL) { continue; } TermOrCompoundTermOrVariableReferer componentTerm = termLink.target; ClassicalConcept componentConcept = @this.memory.conceptualize(subBudget, componentTerm); if (componentConcept != null) { componentConcept.insertTaskLink( new ClassicalTaskLink( task, termLink, subBudget, Parameters.TERM_LINK_RECORD_LENGTH), ctx); } } @this.buildTermLinks(taskBudget); // recursively insert TermLink }
public static bool isTermCompoundTerm(TermOrCompoundTermOrVariableReferer term) { if (term.isAtomic) { return(false); } if (term.isSpecial || term.isVariable) { return(false); } return(true); }
// see https://github.com/opennars/opennars/blob/4515f1d8e191a1f097859decc65153287d5979c5/nars_core/nars/entity/TermLink.java#L137 public bool checkEqual(ClassicalTermLink other) { // triple commented is commented because it's not fully implemented if (other == this) { return(true); } ///if (hashCode() != other.hashCode()) return false; if (other is ClassicalTermLink) { ClassicalTermLink t = (ClassicalTermLink)other; if (type != t.type) { return(false); } if (!(t.index == index)) { return(false); } TermOrCompoundTermOrVariableReferer tt = t.target; if (target == null) { if (tt != null) { return(false); } } else if (tt == null) { if (target != null) { return(false); } } else if (!TermOrCompoundTermOrVariableReferer.isSameWithId(target, t.target)) { return(false); } return(true); } return(false); }
// see https://github.com/opennars/opennars/blob/df5878a54a456c9a692004ae770d4613d31a757d/nars_core/nars/entity/TaskLink.java#L154 /** * To check whether a TaskLink should use a TermLink, return false if they interacted recently * <p> * called in TermLinkBag only * * /param termLink The TermLink to be checked * /param currentTime The current time * /return Whether they are novel to each other */ public bool checkNovel(ClassicalTermLink termLink, long currentTime) { TermOrCompoundTermOrVariableReferer bTerm = termLink.target; if (TermOrCompoundTermOrVariableReferer.isSameWithId(bTerm, targetTask.sentence.term)) { return(false); } ClassicalTermLink linkKey = termLink.name; // iterating the FIFO deque from oldest (first) to newest (last) for (int i = 0; i < records.Count; i++) { Record iRecord = records[i]; if (linkKey.checkEqual(iRecord.link)) { if (currentTime < iRecord.time + Parameters.NOVELTY_HORIZON) { // too recent, not novel return(false); } else { // happened long enough ago that we have forgotten it somewhat, making it seem more novel iRecord.time = currentTime; records.RemoveAt(i); i--; records.Add(iRecord); return(true); } } } // keep recordedLinks queue a maximum finite size while (records.Count + 1 >= recordLength) { records.RemoveAt(0); // remove first } // add knowledge reference to recordedLinks records.Add(new Record(linkKey, currentTime)); return(true); }
/** * Constructor for TermLink template * <p> * called in CompoundTerm.prepareComponentLinks only * /param target Target Term * /param type Link type * /param indices Component indices in compound, may be 1 to 4 */ public ClassicalTermLink(TermOrCompoundTermOrVariableReferer target, EnumType type, params uint[] indices) : base(null) { this.target = target; this.type = type; Debug.Assert(((uint)type % 2) == 0); // template types all point to compound, though the target is component if (type == EnumType.COMPOUND_CONDITION) // the first index is 0 by default { index = new uint[indices.Length + 1]; // index[0] = 0; //first index is zero, but not necessary to set since index[] was just created Array.Copy(indices, 0, index, 1, indices.Length); } else { index = indices; } // OpenNARS hash = init(); }
/* --------------- new task building --------------- */ /** * Shared final operations by all double-premise rules, called from the * rules except StructuralRules * * \param newContent The content of the sentence in task * \param newTruth The truth value of the sentence in task * \param newBudget The budget value in task */ public bool doublePremiseTaskRevised(TermOrCompoundTermOrVariableReferer newContent, TruthValue newTruth, ClassicalBudgetValue newBudget) { ClassicalSentence.MakeByTermPunctuationTruthStampNormalizeParameters makeSentenceParameters = new ClassicalSentence.MakeByTermPunctuationTruthStampNormalizeParameters(); makeSentenceParameters.term = newContent; makeSentenceParameters.punctation = currentTask.sentence.punctation; makeSentenceParameters.truth = newTruth; makeSentenceParameters.stamp = returnTheNewStamp(); ClassicalSentence newSentence = ClassicalSentence.makeByTermPunctuationTruthStampNormalize(makeSentenceParameters); ClassicalTask.MakeParameters makeTaskParameters = new ClassicalTask.MakeParameters(); makeTaskParameters.sentence = newSentence; makeTaskParameters.budget = newBudget; makeTaskParameters.parentTask = currentTask; makeTaskParameters.parentBelief = currentBelief; ClassicalTask newTask = ClassicalTask.make(makeTaskParameters); return(derivedTask(newTask, true, false, null, null, true)); // allows overlap since overlap was already checked on revisable( function // which is not the case for other single premise tasks }
// see https://github.com/opennars/opennars/blob/4515f1d8e191a1f097859decc65153287d5979c5/nars_core/nars/storage/Memory.java#L187 /** * Get the Concept associated to a Term, or create it. * * Doesn't take it from the bag and put it back to save some cycles and to allow better concurrency * Doesn't adjust budget * * if it fails with an soft error (can't take it from the bag etc) it returns null * * doesn't displace concepts * * @param term indicating the concept * @return an existing Concept, or a new one, or null */ public ClassicalConcept conceptualize(ClassicalBudgetValue budget, TermOrCompoundTermOrVariableReferer term) { ClassicalConcept concept = workingCyclish.concepts.referenceByKey(term); if (concept == null) { // CONCURRENCY< lock and put back > // create new concept, with the applied budget concept = new ClassicalConcept(compoundAndTermContext, term, bagBuilder, budget, this); workingCyclish.concepts.putIn(concept); // from java code base // TODO ASK< implement //emit(Events.ConceptNew.class, concept); } else { // legacy java code applies budget here, we don't } return(concept); }
public static ClassicalTermLink makeFromTemplate(TermOrCompoundTermOrVariableReferer term, ClassicalTermLink template, ClassicalBudgetValue budget) { return(new ClassicalTermLink(term, template, budget)); }
public static TemporaryDerivedCompound genBinary(FlagsOfCopula flagsOfCopula, TermOrCompoundTermOrVariableReferer termRefererLeft, TermOrCompoundTermOrVariableReferer termRefererRight) { return(TemporaryDerivedCompound.makeBinaryCompound(flagsOfCopula, TemporaryDerivedCompound.makeLeaf(termRefererLeft), TemporaryDerivedCompound.makeLeaf(termRefererRight))); }
public bool equalsContent(ClassicalSentence s2) { return(TermOrCompoundTermOrVariableReferer.isSameWithId(term, s2.term)); }
// function prototype and some of the methode is like https://github.com/opennars/opennars/blob/4515f1d8e191a1f097859decc65153287d5979c5/nars_core/nars/inference/RuleTables.java#L73 internal static void reason( ClassicalTaskLink taskLink, ClassicalTermLink beliefLink, DerivationContext ctx ) { { // debugging int taskId = taskLink.targetTask.name.term.getAtomicOrTerm; int beliefId = beliefLink.target.getAtomicOrTerm; if (taskId == 300002 && beliefId == 300004) { int breakpointHere2 = 1; } else if (taskId == 300004 && beliefId == 300002) { int breakpointHere2 = 1; } int breakpointHere1 = 1; } Memory memory = ctx.memory; memory.emotion.manageBusy(ctx); ClassicalTask task = ctx.currentTask; ClassicalSentence taskSentence = task.sentence; TermOrCompoundTermOrVariableReferer taskTerm = taskSentence.term; TermOrCompoundTermOrVariableReferer beliefTerm = beliefLink.target; // commented because not jet translated //if (equalSubTermsInRespectToImageAndProduct(taskTerm, beliefTerm)) // return; ClassicalConcept beliefConcept = memory.translateTermToConcept(beliefTerm); ClassicalSentence belief = (beliefConcept != null) ? beliefConcept.getBelief(ctx, task) : null; ctx.currentBelief = belief; if (belief != null) { beliefTerm = belief.term; //because interval handling that differs on conceptual level // too restrictive, its checked for non-deductive inference rules in derivedTask (also for single prem) if (Stamp.checkBaseOverlap(task.sentence.stamp, belief.stamp)) { ctx.evidentalOverlap = true; if (!task.sentence.stamp.isEternal || !belief.stamp.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 //ctx.emit(Events.BeliefReason.class, belief, beliefTerm, taskTerm, nal); if (LocalRules.match(task, belief, ctx)) // new tasks resulted from the match, so return { return; } } // current belief and task may have changed, so set again: ctx.currentBelief = belief; ctx.currentTask = task; // HACK< derivation must be made by combining compounds > if (!TermUtilities.isTermCompoundTerm(taskTerm) || !TermUtilities.isTermCompoundTerm(beliefTerm)) { return; } // derive and create new tasks for the results { IList <TemporaryDerivedCompoundWithDecorationAndTruth> derivedCompoundTermsWithDecorationAndTruth = new List <TemporaryDerivedCompoundWithDecorationAndTruth>(); bool insert = true; DeriverCaller.deriverCaller( ctx.compoundAndTermContext, ctx.compoundAndTermContext.translateToCompoundChecked(taskTerm), ctx.compoundAndTermContext.translateToCompoundChecked(beliefTerm), out derivedCompoundTermsWithDecorationAndTruth, insert); // translate derivedCompoundTermsWithDecorationAndTruth to tasks and add them // for this we have to call DerivationContext.doublePremiseTask() to generate the tasks foreach (var iDerivedWithDecorationAndTruth in derivedCompoundTermsWithDecorationAndTruth) { TermOrCompoundTermOrVariableReferer content = iDerivedWithDecorationAndTruth.derivedCompoundWithDecoration.termReferer; bool temporalInduction = false; // TODO< decide by rule? from the deriver? > bool overlapAllowed = false; // TODO< decide by rule? from the deriver? > TruthValue truth = null; truth = RuleTable.calcTruthDoublePremise(task.sentence.truth, belief.truth, iDerivedWithDecorationAndTruth.truthfunction); ClassicalBudgetValue budget = new ClassicalBudgetValue(0.5f, 0.5f, 0.5f); // TODO< calculate budget by table > ctx.doublePremiseTask(content, truth, budget, temporalInduction, overlapAllowed ); } } }
// see https://github.com/opennars/opennars/blob/4515f1d8e191a1f097859decc65153287d5979c5/nars_core/nars/control/DerivationContext.java#L217 /** * Shared final operations by all double-premise rules, called from the * rules except StructuralRules * * /param newContent The content of the sentence in task * /param newTruth The truth value of the sentence in task * /param newBudget The budget value in task * /param temporalInduction * /param overlapAllowed // https://groups.google.com/forum/#!topic/open-nars/FVbbKq5En-M */ public IList <ClassicalTask> doublePremiseTask( TermOrCompoundTermOrVariableReferer newContent, TruthValue newTruth, ClassicalBudgetValue newBudget, bool temporalInduction, bool overlapAllowed ) { IList <ClassicalTask> ret = new List <ClassicalTask>(); if (newContent == null) { return(null); } if (!newBudget.isAboveThreshold) { return(null); } if ( newContent == null /* commented because not implemented || * ((newContent instanceof Interval)) || * ((newContent instanceof Variable))*/ ) { return(null); } /* commented because not implemented * if (newContent.subjectOrPredicateIsIndependentVar()) { * return null; * }*/ ClassicalSentence newSentence; ClassicalTask newTask; ClassicalSentence.MakeByTermPunctuationTruthStampNormalizeParameters makeSentenceParameters = new ClassicalSentence.MakeByTermPunctuationTruthStampNormalizeParameters(); makeSentenceParameters.term = newContent; makeSentenceParameters.punctation = currentTask.sentence.punctation; makeSentenceParameters.truth = newTruth; makeSentenceParameters.stamp = returnTheNewStamp(); newSentence = ClassicalSentence.makeByTermPunctuationTruthStampNormalize(makeSentenceParameters); newSentence.producedByTemporalInduction = temporalInduction; ClassicalTask.MakeParameters taskMakeParameters = new ClassicalTask.MakeParameters(); taskMakeParameters.sentence = newSentence; taskMakeParameters.budget = newBudget; taskMakeParameters.parentTask = currentTask; taskMakeParameters.parentBelief = currentBelief; newTask = ClassicalTask.make(taskMakeParameters); if (newTask != null) { bool added = derivedTask(newTask, false, false, null, null, overlapAllowed); if (added) { ret.Add(newTask); } } // "Since in principle it is always valid to eternalize a tensed belief" if (temporalInduction && Parameters.IMMEDIATE_ETERNALIZATION) // temporal induction generated ones get eternalized directly { TruthValue truthEternalized = TruthFunctions.eternalize(newTruth); Stamp st = returnTheNewStamp().clone(); st.isEternal = true; makeSentenceParameters = new ClassicalSentence.MakeByTermPunctuationTruthStampNormalizeParameters(); makeSentenceParameters.term = newContent; makeSentenceParameters.punctation = currentTask.sentence.punctation; makeSentenceParameters.truth = truthEternalized; makeSentenceParameters.stamp = st; newSentence = ClassicalSentence.makeByTermPunctuationTruthStampNormalize(makeSentenceParameters); newSentence.producedByTemporalInduction = temporalInduction; taskMakeParameters = new ClassicalTask.MakeParameters(); taskMakeParameters.sentence = newSentence; taskMakeParameters.budget = newBudget; taskMakeParameters.parentTask = currentTask; taskMakeParameters.parentBelief = currentBelief; newTask = ClassicalTask.make(taskMakeParameters); if (newTask != null) { bool added = derivedTask(newTask, false, false, null, null, overlapAllowed); if (added) { ret.Add(newTask); } } } return(ret); }
static void insertDerivedCompoundTerm(CompoundAndTermContext compoundAndTermContext, TemporaryDerivedCompoundWithDecoration derivedCompoundTerm) { // TODO< good place to hook in (compound)term compression > // the index of the compound in the compound table is returned with the decoration of the argument "derivedCompoundTerm" void innerFnInsertIfItDoesntExistRecursivly(TemporaryDerivedCompoundWithDecoration derivedCompoundTermInner) { // recurse to children if (derivedCompoundTermInner.type == TemporaryDerivedCompoundWithDecoration.EnumType.COMPOUND) { innerFnInsertIfItDoesntExistRecursivly(derivedCompoundTermInner.leftChildren); innerFnInsertIfItDoesntExistRecursivly(derivedCompoundTermInner.rightChildren); } // create if not exist if (derivedCompoundTermInner.type == TemporaryDerivedCompoundWithDecoration.EnumType.COMPOUND) // is a Temporary compound(term) { bool innerFnEarlyTestExistsCompound() { var childrenCompoundsWithDecorations = new TemporaryDerivedCompoundWithDecoration[] { derivedCompoundTermInner.leftChildren, derivedCompoundTermInner.rightChildren }; return(compoundAndTermContext.existTermTuple(new List <TermOrCompoundTermOrVariableReferer>(childrenCompoundsWithDecorations.Select(n => n.decoration.returnReferer(compoundAndTermContext))))); } // returns compoundIndex CompoundIndex innerFnCreateCompoundAndAddToReasoner(TermTupleIndex termTupleIndex) { // create compound ulong compoundIndex2 = compoundAndTermContext.getCompoundCreateIndex(); // get the index where the compound will be created Compound.MakeParameters compoundMakeParameters2 = new Compound.MakeParameters(); compoundMakeParameters2.termComplexity = derivedCompoundTermInner.termComplexity; compoundMakeParameters2.flagsOfCopula = derivedCompoundTermInner.flagsOfCopula; compoundMakeParameters2.thisTermReferer = TermOrCompoundTermOrVariableReferer.makeNonatomic(/* 32 bit conversion*/ (int)compoundIndex2); // create new referer based on the compound index compoundMakeParameters2.termTupleIndex = termTupleIndex; Compound createdCompound = compoundAndTermContext.createCompound(compoundMakeParameters2); // insert compound compoundAndTermContext.addCompound(createdCompound); return(CompoundIndex.make(/*quick and dirty conversation*/ (uint)compoundIndex2)); } // build the term, calculate the hash, try to lookup the compound based on the hash // if it exists we return the compoundIndex of the found compound // if it doesn't exist we create a new Compound and return it if (innerFnEarlyTestExistsCompound()) // if the term tuple exists then the compound could exist // build compound and calc hash and try to look it up and compare it to the built compound { var childrenCompoundsWithDecorations = new TemporaryDerivedCompoundWithDecoration[] { derivedCompoundTermInner.leftChildren, derivedCompoundTermInner.rightChildren }; TermTupleIndex termTupleIndex = compoundAndTermContext.getTermTupleIndexByReferers(childrenCompoundsWithDecorations.Select(n => n.decoration.returnReferer(compoundAndTermContext)).ToArray <TermOrCompoundTermOrVariableReferer>()); // * build compound Compound.MakeParameters compoundMakeParameters = new Compound.MakeParameters(); compoundMakeParameters.termComplexity = derivedCompoundTermInner.termComplexity; compoundMakeParameters.flagsOfCopula = derivedCompoundTermInner.flagsOfCopula; //compoundMakeParameters.compoundId; we don't need to initialize it because the hash computation for this lookup doesn't use it // the hash computation doesn't use it because we don't know it //compoundMakeParameters.thisTermReferer we don't need to intialize it because it's not used for hash computation compoundMakeParameters.termTupleIndex = termTupleIndex; Compound createdCompoundForHash = Compound.make(compoundMakeParameters); // * calc hash createdCompoundForHash.updateHash(/*with compoundId*/ false); // * lookup hash and compare if possible // if the compound doesn't exist we create and add it CompoundIndex compoundIndex2; if (compoundAndTermContext.existsCompoundWithoutCompoundId(createdCompoundForHash, out compoundIndex2)) { // set as the result the compound derivedCompoundTermInner.decoration.compoundIndex = compoundIndex2; } else { // create and add compound compoundIndex2 = innerFnCreateCompoundAndAddToReasoner(termTupleIndex); // set as the result the compound derivedCompoundTermInner.decoration.compoundIndex = compoundIndex2; } } else // if the term tuple doesn't exist then the compound can't exist so we have to create and return it // create termTuple { var childrenCompoundsWithDecorations = new TemporaryDerivedCompoundWithDecoration[] { derivedCompoundTermInner.leftChildren, derivedCompoundTermInner.rightChildren }; TermTupleIndex termTupleIndex = compoundAndTermContext.addTermTupleByReferers(childrenCompoundsWithDecorations.Select(n => n.decoration.returnReferer(compoundAndTermContext)).ToArray()); // create and add compound CompoundIndex compoundIndex = innerFnCreateCompoundAndAddToReasoner(termTupleIndex); // set as the result the compound derivedCompoundTermInner.decoration.compoundIndex = compoundIndex; } } else if ( derivedCompoundTermInner.type == TemporaryDerivedCompoundType <TemporaryDerivedCompoundDecoration> .EnumType.LEAF || derivedCompoundTermInner.type == TemporaryDerivedCompoundType <TemporaryDerivedCompoundDecoration> .EnumType.INDEPENDENTVARIABLE || derivedCompoundTermInner.type == TemporaryDerivedCompoundType <TemporaryDerivedCompoundDecoration> .EnumType.DEPENDENTVARIABLE ) { if (derivedCompoundTermInner.type == TemporaryDerivedCompoundType <TemporaryDerivedCompoundDecoration> .EnumType.LEAF) { TermOrCompoundTermOrVariableReferer termReferer = derivedCompoundTermInner.termReferer; derivedCompoundTermInner.decoration.referer = termReferer; } /* commented because we have to figure out how to translate the variable id's * * else if( derivedCompoundTermInner.type == TemporaryDerivedCompoundType<TemporaryDerivedCompoundDecoration>.EnumType.INDEPENDENTVARIABLE ) { * compoundId = derivedCompoundTermInner.independentVariableId; // ASSUMPTION< compoundId is the id of the variable > * } * else if( derivedCompoundTermInner.type == TemporaryDerivedCompoundType<TemporaryDerivedCompoundDecoration>.EnumType.DEPENDENTVARIABLE ) { * compoundId = derivedCompoundTermInner.dependentVariableId; // ASSUMPTION< compoundId is the id of the variable > * } */ else { throw new Exception("Internal error"); } } else { throw new Exception("Internal error"); } } // for now we just check for the existence and insert it recursivly innerFnInsertIfItDoesntExistRecursivly(derivedCompoundTerm); }
// see https://github.com/opennars/opennars/blob/4515f1d8e191a1f097859decc65153287d5979c5/nars_core/nars/storage/Memory.java#L169 /** * Get an existing Concept for a given name * * /param t the name of a concept * /return a Concept or null */ public ClassicalConcept translateTermToConcept(TermOrCompoundTermOrVariableReferer term) { return(workingCyclish.concepts.referenceByKey(term)); }