/****************************************************************************** * This function is invoked in case no existing goals are found related to the * input emotion. Goals are inferred here. * Examples: * in: [embarrassment Jim] [suffocation Jim] * rel: failure-emotion-of activated-emotion-of * goal_status:failed-goal active_goal * goal_class: p-social-esteem s-air * infer: [failed-goal J. [p-social-esteem J.]] [active-goal Jim * [s-air Jim]] ******************************************************************************/ Bool UA_Emotion_NewGoals(Actor *ac, Ts *ts, Obj *a, Obj *in, Obj *rel, Obj *goal_status) { Obj *goal_class; Subgoal *sg; if (!(goal_class = DbGetRelationValue1(&TsNA, NULL, rel, I(in, 0), NULL))) { return(0); } if (goal_class == N("goal-objective")) { /* This is not specific enough to bother with. */ return(0); } ContextSetRSN(ac->cx, RELEVANCE_TOTAL, SENSE_MOSTLY, NOVELTY_TOTAL); sg = TG(ac->cx, &ac->cx->story_time.stopts, a, L(goal_class, a, E)); PA_SpinToGoalStatus(ac->cx, sg, goal_status, in); return(1); }
/****************************************************************************** * Top-level Goal Understanding Agent. ******************************************************************************/ void UA_Goal(Actor *ac, Ts *ts, Obj *a, Obj *in) { Obj *goal; Subgoal *sg; if (ISA(N("goal-status"), I(in, 0)) && a == I(in, 1)) { /* Goal is stated explicitly. * Examples: * [active-goal Jim [s-employment Jim]] * [succeeded-goal Jim [s-employment Jim]] * [failed-goal Jim [s-employment Jim]] * Note that emotional responses occur as a result of spinning * the goal. */ goal = I(in, 2); /* If <in> corresponds to existing subgoal, steer that subgoal according * to <in>. */ for (sg = ac->subgoals; sg; sg = sg->next) { if (ObjSimilarList(goal, sg->obj)) { UA_GoalSetStatus(ac, sg, I(in, 0), NULL); return; } } /* This is a new subgoal. */ /* todo: Add more heuristics for making sense. * For example, N("s-employment") doesn't make sense if <a> already has * a job. */ ContextSetRSN(ac->cx, RELEVANCE_TOTAL, SENSE_TOTAL, NOVELTY_TOTAL); if ((sg = TG(ac->cx, &ac->cx->story_time.stopts, a, goal))) { PA_SpinToGoalStatus(ac->cx, sg, I(in, 0), NULL); } } else if (ISA(N("prep-goal-for"), I(in, 0))) { UA_GoalSubgoal(ac, ts, a, in, I(in, 2), I(in, 1)); } else if (ISA(N("intends"), I(in, 0))) { UA_GoalSubgoal(ac, ts, a, in, I(in, 1), I(in, 2)); } }
void UA_GoalSetStatus(Actor *ac, Subgoal *sg, Obj *new_status, Obj *spin_emotion) { Obj *prev_status; prev_status = SubgoalStatus(sg); if (prev_status == new_status) { /* No change in this subgoal's status. */ /* todo: This case isn't needed because existing goals should already have * created these associated emotions and hence the existing emotion would * be found in UA_Emotion? */ ContextSetRSN(ac->cx, RELEVANCE_TOTAL, SENSE_TOTAL, NOVELTY_EXPECTED); return; } if (new_status == N("active-goal")) { /* Flashback? */ ContextSetRSN(ac->cx, RELEVANCE_TOTAL, SENSE_HALF, NOVELTY_TOTAL); } else { /* Possible irony. */ ContextSetRSN(ac->cx, RELEVANCE_TOTAL, SENSE_LITTLE, NOVELTY_TOTAL); ContextAddNotMakeSenseReason(ac->cx, sg->cur_goal); } PA_SpinToGoalStatus(ac->cx, sg, new_status, spin_emotion); }