class AnswerDistance_IntentionAction extends IntentionAction { canHandle(intention:Term, ai:RuleBasedAI) : boolean { if (intention.functor.is_a(ai.o.getSort("action.answer.distance"))) return true; return false; } execute(ir:IntentionRecord, ai:RuleBasedAI) : boolean { this.ir = ir; let intention:Term = ir.action; let requester:TermAttribute = ir.requester; let o1ID:string = null; let o2ID:string = null; let units:Sort = ai.o.getSort("meter"); if (intention.attributes.length>=4) { if (intention.attributes[2] instanceof ConstantTermAttribute) { o1ID = (intention.attributes[2]).value; } if (intention.attributes[3] instanceof ConstantTermAttribute) { o2ID = (intention.attributes[3]).value; } } if (intention.attributes.length>=5) units = intention.attributes[4].sort; if (o1ID == null || o2ID == null) { if (requester != null) { let term:Term = Term.fromString("action.talk('"+ai.selfID+"'[#id], perf.inform.answer("+intention.attributes[1]+",'unknown'[symbol]))", ai.o); ai.intentions.push(new IntentionRecord(term, intention.attributes[1], null, null, ai.timeStamp)); } ir.succeeded = false; return true; } let d:number = ai.distanceBetweenIds(o1ID, o2ID); if (d != null) { let d2:number = null; d2 = this.convertToUnits(d, units); if (d2 != null) { d = d2; } else { units = ai.o.getSort("meter"); } if (requester != null) { // we know the answer already without inference! let term:Term = Term.fromString("action.talk('"+ai.selfID+"'[#id], perf.inform.answer("+intention.attributes[1]+",'"+d+"'["+units.name+"]))", ai.o); ai.intentions.push(new IntentionRecord(term, null, null, null, ai.timeStamp)); } ir.succeeded = true; return true; } // launch an inference process: { let newPerformative:Term = Term.fromString("action.answer.distance('"+ai.selfID+"'[#id], "+requester+", perf.q.query('"+ai.selfID+"'[#id], DISTANCE, distance('"+o1ID+"'[#id],'"+o2ID+"'[#id], DISTANCE)))", ai.o); let negated_s_l:Sentence[] = Term.termToSentences(new Term(ai.o.getSort("#not"), [((newPerformative.attributes[2])).term.attributes[2]]), ai.o); ai.queuedInferenceProcesses.push(new InferenceRecord(ai, [], [negated_s_l], 1, 0, false, null, new AnswerQuery_InferenceEffect(newPerformative, ir.requestingPerformative))); // TODO: this should have some temporary value (in all actions that require inference or continuous execution) // that is then replaced with true/false after inference/continuous is done ir.succeeded = true; } // if (requester != null) { // let term:Term = Term.fromString("action.talk('"+ai.selfID+"'[#id], perf.inform.answer("+intention.attributes[1]+",'unknown'[symbol]))", ai.o); // ai.intentions.push(new IntentionRecord(term, intention.attributes[1], null, null, ai.timeStamp)); // } return true; } convertToUnits(meters:number, unit:Sort) : number { /* */ if (unit.name == "milimiter") return meters*1000; if (unit.name == "meter") return meters; if (unit.name == "kilometer") return meters/1000; if (unit.name == "light-year") return meters/9.461E15; return null; } saveToXML(ai:RuleBasedAI) : string { return ""; } static loadFromXML(xml:Element, ai:RuleBasedAI) : IntentionAction { return new AnswerDistance_IntentionAction(); } }