Skip to content
Snippets Groups Projects
Commit ffd5d47b authored by peiwang's avatar peiwang
Browse files

temporal induction inference

parent d9204580
No related branches found
No related tags found
No related merge requests found
......@@ -16,7 +16,10 @@
*/
package nars.inference;
import nars.language.CompoundTerm;
import nars.core.Parameters;
import nars.entity.*;
import nars.language.*;
import nars.storage.*;
/**
*
......@@ -37,7 +40,7 @@ public class TemporalRules {
return -order;
}
}
public static boolean matchingOrder(int order1, int order2) {
return (order1 == order2) || (order1 == ORDER_NONE) || (order2 == ORDER_NONE);
}
......@@ -110,4 +113,40 @@ public class TemporalRules {
return order;
}
public static void temporalInduction(Sentence s1, Sentence s2, Memory memory) {
Term t1 = s1.cloneContent();
Term t2 = s2.cloneContent();
if (Statement.invalidStatement(t1, t2)) {
return;
}
long time1 = s1.getOccurenceTime();
long time2 = s2.getOccurenceTime();
long timeDiff = time2 - time1;
Interval interval = null;
if (Math.abs(timeDiff) > Parameters.DURATION) {
interval = new Interval(Math.abs(timeDiff));
}
int order;
if (timeDiff > Parameters.DURATION) {
order = TemporalRules.ORDER_FORWARD;
} else if (timeDiff < -Parameters.DURATION) {
order = TemporalRules.ORDER_BACKWARD;
} else {
order = TemporalRules.ORDER_CONCURRENT;
}
TruthValue givenTruth1 = s1.getTruth();
TruthValue givenTruth2 = s2.getTruth();
TruthValue truth1 = TruthFunctions.abduction(givenTruth1, givenTruth2);
TruthValue truth2 = TruthFunctions.abduction(givenTruth2, givenTruth1);
TruthValue truth3 = TruthFunctions.comparison(givenTruth1, givenTruth2);
BudgetValue budget1 = BudgetFunctions.forward(truth1, memory);
BudgetValue budget2 = BudgetFunctions.forward(truth2, memory);
BudgetValue budget3 = BudgetFunctions.forward(truth3, memory);
Statement statement1 = Implication.make(t1, t2, order, memory);
Statement statement2 = Implication.make(t2, t1, reverseOrder(order), memory);
Statement statement3 = Equivalence.make(t1, t2, order, memory);
memory.doublePremiseTask(statement1, truth1, budget1);
memory.doublePremiseTask(statement2, truth2, budget2);
memory.doublePremiseTask(statement3, truth3, budget3);
}
}
......@@ -26,26 +26,17 @@ import java.util.List;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import nars.entity.BudgetValue;
import nars.entity.Concept;
import nars.entity.Item;
import nars.entity.Sentence;
import nars.entity.Stamp;
import nars.entity.Task;
import nars.entity.TaskLink;
import nars.entity.TermLink;
import nars.entity.TruthValue;
import nars.inference.BudgetFunctions;
import nars.inference.InferenceRecorder;
import nars.entity.*;
import nars.inference.*;
import nars.language.Term;
import nars.core.Parameters;
import nars.core.NAR;
import nars.core.*;
import nars.io.Output.OUT;
/**
* The memory of the system.
*/
public class Memory {
public class Memory {
public static Random randomNumber = new Random(1);
/**
......@@ -66,7 +57,7 @@ public class Memory {
* Inference record text to be written into a log file
*/
private InferenceRecorder recorder;
public final AtomicInteger beliefForgettingRate = new AtomicInteger(Parameters.TERM_LINK_FORGETTING_CYCLE);
public final AtomicInteger taskForgettingRate = new AtomicInteger(Parameters.TASK_LINK_FORGETTING_CYCLE);
public final AtomicInteger conceptForgettingRate = new AtomicInteger(Parameters.CONCEPT_FORGETTING_CYCLE);
......@@ -111,7 +102,13 @@ public class Memory {
* TODO unused
*/
protected HashMap<Term, Term> substitute;
// for temporal induction
Task lastEvent;
public BudgetValue getLastEventBudget() {
return lastEvent.getBudget();
}
/* ---------- Constructor ---------- */
......@@ -152,9 +149,10 @@ public class Memory {
return nar.getTime();
}
/**
* Actually means that there are no new Tasks
*
* @return Whether the newTasks list is empty
*/
public boolean noResult() {
return newTasks.isEmpty();
......@@ -213,13 +211,12 @@ public class Memory {
Concept concept = concepts.get(n);
if (concept == null) {
// The only part of NARS that instantiates new Concepts
concept = new Concept(term, this);
concept = new Concept(term, this);
final boolean created = concepts.putIn(concept);
if (!created) {
return null;
}
else {
} else {
if (recorder.isActive()) {
recorder.onConceptNew(concept);
}
......@@ -255,28 +252,30 @@ public class Memory {
}
/* ---------- new task entries ---------- */
/** add new task that waits to be processed in the next workCycle */
/**
* add new task that waits to be processed in the next workCycle
*/
protected void addNewTask(final Task t, final String reason) {
newTasks.add(t);
if (recorder.isActive()) {
recorder.onTaskAdd(t, reason);
}
}
/* There are several types of new tasks, all added into the
newTasks list, to be processed in the next workCycle.
Some of them are reported and/or logged. */
/**
* Input task processing. Invoked by the outside or inside environment.
Outside: StringParser (addInput); Inside: Operator (feedback). Input tasks
with low priority are ignored, and the others are put into task buffer.
* Outside: StringParser (addInput); Inside: Operator (feedback). Input
* tasks with low priority are ignored, and the others are put into task
* buffer.
*
* @param task The addInput task
*/
public void inputTask(final Task task) {
if (task.getBudget().aboveThreshold()) {
addNewTask(task, "Perceived");
if (task.getBudget().aboveThreshold()) {
addNewTask(task, "Perceived");
} else {
if (recorder.isActive()) {
recorder.onTaskRemove(task, "Neglected");
......@@ -295,7 +294,7 @@ public class Memory {
*/
public void activatedTask(final BudgetValue budget, final Sentence sentence, final Sentence candidateBelief) {
final Task task = new Task(sentence, budget, currentTask, sentence, candidateBelief);
if (sentence.isQuestion()) {
final float s = task.getBudget().summary();
final float minSilent = nar.param.getSilenceLevel() / 100.0f;
......@@ -303,8 +302,8 @@ public class Memory {
nar.output(OUT.class, task.getSentence());
}
}
addNewTask(task, "Activated");
addNewTask(task, "Activated");
}
/**
......@@ -316,7 +315,7 @@ public class Memory {
if (task.getBudget().aboveThreshold()) {
if (task.getSentence() != null && task.getSentence().getTruth() != null) {
float conf = task.getSentence().getTruth().getConfidence();
if (conf == 0) {
if (conf == 0) {
//no confidence - we can delete the wrongs out that way.
if (recorder.isActive()) {
recorder.onTaskRemove(task, "Ignored");
......@@ -326,16 +325,16 @@ public class Memory {
}
final Stamp stamp = task.getSentence().getStamp();
final List<Term> chain = stamp.getChain();
if (currentBelief != null) {
if (currentBelief != null) {
final Term currentBeliefContent = currentBelief.getContent();
if(chain.contains(currentBeliefContent)) {
if (chain.contains(currentBeliefContent)) {
chain.remove(currentBeliefContent);
}
stamp.addToChain(currentBeliefContent, task.getSentence());
}
if (currentTask!=null) {
if (currentTask != null) {
final Term currentTaskContent = currentTask.getContent();
//workaround for single premise task issue:
......@@ -348,13 +347,13 @@ public class Memory {
//end workaround
if (!single) {
if(chain.contains(currentTaskContent)) {
if (chain.contains(currentTaskContent)) {
chain.remove(currentTaskContent);
}
stamp.addToChain(currentTaskContent, task.getSentence());
}
}
if (!revised) { //its a inference rule, we have to do the derivation chain check to hamper cycles
for (int i = 0; i < chain.size(); i++) {
final Term chain1 = chain.get(i);
......@@ -369,10 +368,10 @@ public class Memory {
final int stampLength = stamp.length();
for (int i = 0; i < stampLength; i++) {
final long baseI = stamp.getBase()[i];
for (int j = 0; j < stampLength; j++) {
if ((i != j) && (baseI == stamp.getBase()[j])) {
if (recorder.isActive()) {
if (recorder.isActive()) {
recorder.onTaskRemove(task, "Overlapping Evidence on Revision");
}
return;
......@@ -385,13 +384,13 @@ public class Memory {
if (budget > minSilent) { // only report significant derived Tasks
nar.output(OUT.class, task.getSentence());
}
if (recorder.isActive()) {
if (recorder.isActive()) {
addNewTask(task, "Derived");
}
} else {
} else {
if (recorder.isActive()) {
recorder.onTaskRemove(task, "Ignored");
}
}
}
}
......@@ -445,7 +444,6 @@ public class Memory {
// derivedTask(newTask, false, false);
// }
// }
/**
* Shared final operations by all single-premise rules, called in
* StructuralRules
......@@ -489,8 +487,6 @@ public class Memory {
derivedTask(newTask, false, true);
}
/* ---------- system working workCycle ---------- */
/**
* An atomic working cycle of the system: process new Tasks, then fire a
......@@ -501,48 +497,56 @@ public class Memory {
* @param clock The current time to be displayed
*/
public void workCycle(final long clock) {
if (recorder.isActive()) {
if (recorder.isActive()) {
recorder.preCycle(clock);
}
processNewTask();
if (noResult()) { // necessary?
processNovelTask();
}
if (noResult()) { // necessary?
processConcept();
}
novelTasks.refresh();
if (recorder.isActive()) {
if (recorder.isActive()) {
recorder.postCycle(clock);
}
}
}
/**
* Process the newTasks accumulated in the previous workCycle, accept addInput
ones and those that corresponding to existing concepts, plus one from the
buffer.
* Process the newTasks accumulated in the previous workCycle, accept
* addInput ones and those that corresponding to existing concepts, plus one
* from the buffer.
*/
private void processNewTask() {
// don't include new tasks produced in the current workCycle
int counter = newTasks.size();
int counter = newTasks.size();
Task newEvent = null;
while (counter-- > 0) {
final Task task = newTasks.removeFirst();
if (task.isInput() || (termToConcept(task.getContent()) != null)) {
if (task.isInput() || (termToConcept(task.getContent()) != null)) {
// new addInput or existing concept
immediateProcess(task);
if (task.getSentence().getStamp().getOccurrenceTime() != Stamp.ETERNAL) {
if ((newEvent == null)
|| (BudgetFunctions.rankBelief(newEvent.getSentence())
< BudgetFunctions.rankBelief(task.getSentence()))) {
newEvent = task;
}
}
} else {
final Sentence s = task.getSentence();
if (s.isJudgment()) {
final double exp = s.getTruth().getExpectation();
if (exp > Parameters.DEFAULT_CREATION_EXPECTATION) {
// new concept formation
novelTasks.putIn(task);
novelTasks.putIn(task);
} else {
if (recorder.isActive()) {
recorder.onTaskRemove(task, "Neglected");
......@@ -551,6 +555,17 @@ public class Memory {
}
}
}
if (newEvent != null) {
if (lastEvent != null) {
newStamp = Stamp.make(newEvent.getSentence().getStamp(), lastEvent.getSentence().getStamp(), getTime());
if (newStamp != null) {
currentTask = newEvent;
currentBelief = lastEvent.getSentence();
TemporalRules.temporalInduction(newEvent.getSentence(), currentBelief, this);
}
}
lastEvent = newEvent;
}
}
/**
......@@ -570,13 +585,13 @@ public class Memory {
currentConcept = concepts.takeOut();
if (currentConcept != null) {
currentTerm = currentConcept.getTerm();
if (recorder.isActive()) {
recorder.append("Concept Selected: " + currentTerm + "\n");
}
concepts.putBack(currentConcept); // current Concept remains in the bag all the time
currentConcept.fire(); // a working workCycle
}
}
......@@ -590,14 +605,14 @@ public class Memory {
*/
private void immediateProcess(final Task task) {
currentTask = task; // one of the two places where this variable is set
if (recorder.isActive()) {
recorder.append("Task Immediately Processed: " + task + "\n");
}
currentTerm = task.getContent();
currentConcept = getConcept(currentTerm);
if (currentConcept != null) {
activateConcept(currentConcept, task.getBudget());
currentConcept.directProcess(task);
......@@ -637,8 +652,6 @@ public class Memory {
novelTasks.addBagObserver(bagObserver, s);
}
@Override
public String toString() {
final StringBuffer sb = new StringBuffer(1024);
......@@ -686,30 +699,54 @@ public class Memory {
public static final NullInferenceRecorder global = new NullInferenceRecorder();
private NullInferenceRecorder() { }
@Override public boolean isActive() { return false; }
private NullInferenceRecorder() {
}
@Override public void init() { }
@Override
public boolean isActive() {
return false;
}
@Override public void show() { }
@Override
public void init() {
}
@Override
public void show() {
}
@Override
public void play() {
}
@Override
public void stop() {
}
@Override
public void append(String s) {
}
@Override
public void preCycle(long clock) {
}
@Override public void play() { }
@Override
public void postCycle(long clock) {
}
@Override public void stop() { }
@Override
public void onConceptNew(Concept concept) {
}
@Override public void append(String s) { }
@Override
public void onTaskAdd(Task task, String reason) {
}
@Override public void preCycle(long clock) { }
@Override public void postCycle(long clock) { }
@Override public void onConceptNew(Concept concept) { }
@Override
public void onTaskRemove(Task task, String reason) {
}
@Override public void onTaskAdd(Task task, String reason) { }
@Override public void onTaskRemove(Task task, String reason) { }
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment