package nars.plugin.mental; import nars.util.Plugin; import java.util.Arrays; import nars.util.EventEmitter.EventObserver; import nars.util.Events; import nars.storage.Memory; import nars.NAR; import nars.config.Parameters; import nars.control.DerivationContext; import nars.entity.BudgetValue; import nars.entity.Sentence; import nars.entity.Stamp; import nars.entity.Task; import nars.entity.TruthValue; import nars.inference.BudgetFunctions; import nars.inference.TemporalRules; import nars.io.Symbols; import nars.language.Conjunction; import nars.language.Implication; import nars.language.Inheritance; import nars.language.Interval; import nars.language.Product; import nars.language.Term; import nars.operator.Operation; import nars.operator.Operator; /** * To rememberAction an internal action as an operation * <p> * called from Concept * @param task The task processed */ public class InternalExperience implements Plugin, EventObserver { public static float MINIMUM_BUDGET_SUMMARY_TO_CREATE=0.92f; //0.92 public static float MINIMUM_BUDGET_SUMMARY_TO_CREATE_WONDER_EVALUATE=0.92f; //internal experience has less durability? public static final float INTERNAL_EXPERIENCE_PROBABILITY=0.0001f; //less probable form public static final float INTERNAL_EXPERIENCE_RARE_PROBABILITY = INTERNAL_EXPERIENCE_PROBABILITY/4f; //internal experience has less durability? public static float INTERNAL_EXPERIENCE_DURABILITY_MUL=0.1f; //0.1 //internal experience has less priority? public static float INTERNAL_EXPERIENCE_PRIORITY_MUL=0.1f; //0.1 //dont use internal experience for want and believe if this setting is true public static boolean AllowWantBelieve=true; // public static boolean OLD_BELIEVE_WANT_EVALUATE_WONDER_STRATEGY=false; //https://groups.google.com/forum/#!topic/open-nars/DVE5FJd7FaM public boolean isAllowNewStrategy() { return !OLD_BELIEVE_WANT_EVALUATE_WONDER_STRATEGY; } public void setAllowNewStrategy(boolean val) { OLD_BELIEVE_WANT_EVALUATE_WONDER_STRATEGY=!val; } public boolean isAllowWantBelieve() { return AllowWantBelieve; } public void setAllowWantBelieve(boolean val) { AllowWantBelieve=val; } public double getMinCreationBudgetSummary() { return MINIMUM_BUDGET_SUMMARY_TO_CREATE; } public void setMinCreationBudgetSummary(double val) { MINIMUM_BUDGET_SUMMARY_TO_CREATE=(float) val; } public double getMinCreationBudgetSummaryWonderEvaluate() { return MINIMUM_BUDGET_SUMMARY_TO_CREATE_WONDER_EVALUATE; } public void setMinCreationBudgetSummaryWonderEvaluate(double val) { MINIMUM_BUDGET_SUMMARY_TO_CREATE_WONDER_EVALUATE=(float) val; } private Memory memory; /** whether it is full internal experience, or minimal (false) */ public boolean isFull() { return false; } public static boolean enabled=false; @Override public boolean setEnabled(NAR n, boolean enable) { memory = n.memory; memory.event.set(this, enable, Events.ConceptDirectProcessedTask.class); if (isFull()) memory.event.set(this, enable, Events.BeliefReason.class); enabled=enable; return true; } public static Term toTerm(final Sentence s, final Memory mem) { String opName; switch (s.punctuation) { case Symbols.JUDGMENT_MARK: opName = "^believe"; if(!AllowWantBelieve) { return null; } break; case Symbols.GOAL_MARK: opName = "^want"; if(!AllowWantBelieve) { return null; } break; case Symbols.QUESTION_MARK: opName = "^wonder"; break; case Symbols.QUEST_MARK: opName = "^evaluate"; break; default: return null; } Term opTerm = mem.getOperator(opName); Term[] arg = new Term[ s.truth==null ? 1 : 2 ]; arg[0]=s.getTerm(); if (s.truth != null) { arg[1] = s.truth.toWordTerm(); } //Operation.make ? Term operation = Inheritance.make(new Product(arg), opTerm); if (operation == null) { throw new RuntimeException("Unable to create Inheritance: " + opTerm + ", " + Arrays.toString(arg)); } return operation; } @Override public void event(Class event, Object[] a) { if (event==Events.ConceptDirectProcessedTask.class) { Task task = (Task)a[0]; //old strategy always, new strategy only for QUESTION and QUEST: if(OLD_BELIEVE_WANT_EVALUATE_WONDER_STRATEGY || (!OLD_BELIEVE_WANT_EVALUATE_WONDER_STRATEGY && (task.sentence.punctuation == Symbols.QUESTION_MARK || task.sentence.punctuation == Symbols.QUEST_MARK))) { InternalExperienceFromTaskInternal(memory,task,isFull()); } } else if (event == Events.BeliefReason.class) { //belief, beliefTerm, taskTerm, nal Sentence belief = (Sentence)a[0]; Term beliefTerm = (Term)a[1]; Term taskTerm = (Term)a[2]; DerivationContext nal = (DerivationContext)a[3]; beliefReason(belief, beliefTerm, taskTerm, nal); } } public static void InternalExperienceFromBelief(Memory memory, Task task, Sentence belief) { Task T=new Task(belief.clone(),task.budget.clone(),null); InternalExperienceFromTask(memory,T,false); } public static void InternalExperienceFromTask(Memory memory, Task task, boolean full) { if(!OLD_BELIEVE_WANT_EVALUATE_WONDER_STRATEGY) { InternalExperienceFromTaskInternal(memory,task,full); } } public static boolean InternalExperienceFromTaskInternal(Memory memory, Task task, boolean full) { if(!enabled) { return false; } // if(OLD_BELIEVE_WANT_EVALUATE_WONDER_STRATEGY || // (!OLD_BELIEVE_WANT_EVALUATE_WONDER_STRATEGY && (task.sentence.punctuation==Symbols.QUESTION_MARK || task.sentence.punctuation==Symbols.QUEST_MARK))) { { if(task.sentence.punctuation == Symbols.QUESTION_MARK || task.sentence.punctuation == Symbols.QUEST_MARK) { if(task.budget.summary()<MINIMUM_BUDGET_SUMMARY_TO_CREATE_WONDER_EVALUATE) { return false; } } else if(task.budget.summary()<MINIMUM_BUDGET_SUMMARY_TO_CREATE) { return false; } } Term content=task.getTerm(); // to prevent infinite recursions if (content instanceof Operation/* || Memory.randomNumber.nextDouble()>Parameters.INTERNAL_EXPERIENCE_PROBABILITY*/) { return true; } Sentence sentence = task.sentence; TruthValue truth = new TruthValue(1.0f, Parameters.DEFAULT_JUDGMENT_CONFIDENCE); Stamp stamp = task.sentence.stamp.clone(); stamp.setOccurrenceTime(memory.time()); Term ret=toTerm(sentence, memory); if (ret==null) { return true; } Sentence j = new Sentence(ret, Symbols.JUDGMENT_MARK, truth, stamp); BudgetValue newbudget=new BudgetValue( Parameters.DEFAULT_JUDGMENT_CONFIDENCE*INTERNAL_EXPERIENCE_PRIORITY_MUL, Parameters.DEFAULT_JUDGMENT_PRIORITY*INTERNAL_EXPERIENCE_DURABILITY_MUL, BudgetFunctions.truthToQuality(truth)); if(!OLD_BELIEVE_WANT_EVALUATE_WONDER_STRATEGY) { newbudget.setPriority(task.getPriority()*INTERNAL_EXPERIENCE_PRIORITY_MUL); newbudget.setDurability(task.getDurability()*INTERNAL_EXPERIENCE_DURABILITY_MUL); } Task newTask = new Task(j, (BudgetValue) newbudget, full ? null : task); memory.addNewTask(newTask, "Remembered Action (Internal Experience)"); return false; } final static String[] nonInnateBeliefOperators = new String[] { "^remind","^doubt","^consider","^evaluate","hestitate","^wonder","^belief","^want" }; /** used in full internal experience mode only */ protected void beliefReason(Sentence belief, Term beliefTerm, Term taskTerm, DerivationContext nal) { Memory memory = nal.memory; if (Memory.randomNumber.nextDouble() < INTERNAL_EXPERIENCE_RARE_PROBABILITY ) { //the operators which dont have a innate belief //also get a chance to reveal its effects to the system this way Operator op=memory.getOperator(nonInnateBeliefOperators[Memory.randomNumber.nextInt(nonInnateBeliefOperators.length)]); Product prod=new Product(new Term[]{belief.term}); if(op!=null && prod!=null) { Term new_term=Inheritance.make(prod, op); Sentence sentence = new Sentence( new_term, Symbols.GOAL_MARK, new TruthValue(1, Parameters.DEFAULT_JUDGMENT_CONFIDENCE), // a naming convension new Stamp(memory)); float quality = BudgetFunctions.truthToQuality(sentence.truth); BudgetValue budget = new BudgetValue( Parameters.DEFAULT_GOAL_PRIORITY*INTERNAL_EXPERIENCE_PRIORITY_MUL, Parameters.DEFAULT_GOAL_DURABILITY*INTERNAL_EXPERIENCE_DURABILITY_MUL, quality); Task newTask = new Task(sentence, budget); nal.derivedTask(newTask, false, false, null, null, false); } } if (beliefTerm instanceof Implication && Memory.randomNumber.nextDouble()<=INTERNAL_EXPERIENCE_PROBABILITY) { Implication imp=(Implication) beliefTerm; if(imp.getTemporalOrder()==TemporalRules.ORDER_FORWARD) { //1. check if its (&/,term,+i1,...,+in) =/> anticipateTerm form: boolean valid=true; if(imp.getSubject() instanceof Conjunction) { Conjunction conj=(Conjunction) imp.getSubject(); if(!conj.term[0].equals(taskTerm)) { valid=false; //the expected needed term is not included } for(int i=1;i<conj.term.length;i++) { if(!(conj.term[i] instanceof Interval)) { valid=false; break; } } } else { if(!imp.getSubject().equals(taskTerm)) { valid=false; } } if(valid) { Operator op=memory.getOperator("^anticipate"); if (op == null) throw new RuntimeException(this + " requires ^anticipate operator"); Product args=new Product(new Term[]{imp.getPredicate()}); Term new_term=Operation.make(args,op); Sentence sentence = new Sentence( new_term, Symbols.GOAL_MARK, new TruthValue(1, Parameters.DEFAULT_JUDGMENT_CONFIDENCE), // a naming convension new Stamp(memory)); float quality = BudgetFunctions.truthToQuality(sentence.truth); BudgetValue budget = new BudgetValue( Parameters.DEFAULT_GOAL_PRIORITY*INTERNAL_EXPERIENCE_PRIORITY_MUL, Parameters.DEFAULT_GOAL_DURABILITY*INTERNAL_EXPERIENCE_DURABILITY_MUL, quality); Task newTask = new Task(sentence, budget); nal.derivedTask(newTask, false, false, null, null, false); } } } } }