示例#1
0
/******************************************************************************
 * Top-level Emotion Understanding Agent.
 * todo: Anger reduces friendship level slightly, increases enemy level.
 ******************************************************************************/
void UA_Emotion(Actor *ac, Ts *ts, Obj *a, Obj *in)
{
  Obj		*emot_class, *from, *to;
  ObjList	*p, *causes;
  if (GetActorSpatial(in, a, &from, &to)) {
  /* todo: If you ptrans to a place you like, you are happy. */
  } else if (ISA(N("emotion"), I(in, 0)) &&
             (!ISA(N("attitude"), I(in, 0))) &&
             a == I(in, 1)) {
    /* [happy Jim] [sad Jim] [happy-for Mary Mary-roommate] */
    emot_class = I(in, 0);
    for (p = ac->emotions; p; p = p->next) {
      if (I(p->obj, 0) == emot_class) {
        /* Emotion is same as an existing one: alter intensity.
         * For example, after A canceling an appointment with B, the input
         * "B is angry at A" makes sense because this emotion was
         * already added by the cancel.
         */
        ContextSetRSN(ac->cx, RELEVANCE_TOTAL, SENSE_TOTAL, NOVELTY_EXPECTED);
        if ((causes = CAUSES(p->obj, ac->cx))) {
          ContextAddMakeSenseReasons(ac->cx, causes);
          ObjListFree(causes);
        }
        ObjWeightSet(p->obj, ObjWeight(p->obj) + ObjWeight(in));
        return;
      }
      /* todo: Perhaps handle emotion specifications and generalizations.
       * But this might not have so much meaning: You can be both happy
       * and proud.
       */
    }
    UA_Emotion1(ac, ts, a, in);
    UA_EmotionAdd(ac, ts, in, NULL, NULL);
  }
}
示例#2
0
void ContextSetJustifiedSenses(Context *cx, Float sense,
                               ObjList *justifications)
{
  ContextSetSense(cx, sense);
  if (sense <= SENSE_LITTLE) {
    ContextAddNotMakeSenseReasons(cx, justifications);
  } else if (sense >= SENSE_MOSTLY) {
    ContextAddMakeSenseReasons(cx, justifications);
  }
}
示例#3
0
/******************************************************************************
 * Examples:
 * a:        Jim                    Jim                    Jim
 * other:    Mary                   Mary                   Mary
 * in:       [happy-for Jim Mary]   [sorry-for J. M.]      [gloating J. M.]
 *             (positive-emotion)     (negative-emotion)     (positive-emotion)
 * attitude: like-human             like-human             like-human
 * weight:   WEIGHT_DEFAULT         WEIGHT_DEFAULT         -WEIGHT_DEFAULT
 * o.e.c.:   positive-emotion       negative-emotion       negative-emotion
 * att:      [like-human J. M. WD]  [like-human J. M. WD]  [like-human J. M.
 *                                                          -WD]
 *
 * todo: Generalize this to work for all the related like/love attitudes as well
 *       as friends/enemies relations.
 *       The intensity rules are more complex: something like
 *         value of actor2's emotion = value of actor1's emotion x
 *                                      value of how much actor2 likes actor1.
 ******************************************************************************/
void UA_Emotion_FortunesOfOthers(Actor *ac, Ts *ts, Obj *a, Obj *in,
                                 Obj *other, Float weight,
                                 Obj *other_emot_class)
{
  int		found;
  Float		weight1;
  Obj		*other_emot_class1;
  ObjList	*causes, *objs, *atts, *p, *q;

  /* Relate <a>'s emotion to <a>'s attitudes. */
  if (0.0 != (weight1 = UA_FriendAttitude(ts, a, other, 1, &atts))) {
    if (FloatSign(weight1) == FloatSign(weight)) {
    /* The input emotion agrees with known attitudes. */
      ContextSetRSN(ac->cx, RELEVANCE_TOTAL, SENSE_TOTAL, NOVELTY_HALF);
      ContextAddMakeSenseReasons(ac->cx, atts);
    } else {
    /* The input emotion disagrees with known attitudes. */
      ContextSetRSN(ac->cx, RELEVANCE_TOTAL, SENSE_LITTLE, NOVELTY_TOTAL);
      ContextAddNotMakeSenseReasons(ac->cx, atts);
    }
  } else {
    /* Attitude of <a> toward <other> is unknown. */
    ContextSetRSN(ac->cx, RELEVANCE_TOTAL, SENSE_MOSTLY, NOVELTY_MOSTLY);
    UA_Infer(ac->cx->dc, ac->cx, ts,
             L(N("like-human"), a, other, NumberToObj(weight), E), in);
  }

  /* Relate <a>'s emotion to <other>'s emotion.
   * found = <other>'s emotion implied by <a>'s emotion is already known,
   * excluding motivating emotions.
   */
  objs = RD(ts, L(other_emot_class, other, E), 0);
  found = 0;
  for (p = objs; p; p = p->next) {
    if (ISA(N("motivation"), I(p->obj, 0))) continue;
    if ((causes = CAUSES(p->obj, ac->cx))) {
      for (q = causes; q; q = q->next) {
        if (!ISA(N("active-goal"), I(q->obj, 0))) {
          found = 1;
          ContextSetRSN(ac->cx, RELEVANCE_TOTAL, SENSE_TOTAL, NOVELTY_HALF);
          ContextAddMakeSenseReason(ac->cx, q->obj);
        }
      }
    } else {
      found = 1;
      ContextSetRSN(ac->cx, RELEVANCE_TOTAL, SENSE_TOTAL, NOVELTY_HALF);
      ContextAddMakeSenseReason(ac->cx, p->obj);
    }
    ObjListFree(causes);
  }
  ObjListFree(objs);

  if (!found) {
    /* <other>'s emotion implied by <a>'s emotion is not yet known. */
    ContextSetRSN(ac->cx, RELEVANCE_TOTAL, SENSE_MOSTLY, NOVELTY_MOSTLY);
    if (other_emot_class == N("positive-emotion")) {
      other_emot_class1 = N("happiness");
    } else if (other_emot_class == N("negative-emotion")) {
      other_emot_class1 = N("sadness");
    } else {
      other_emot_class1 = other_emot_class;
    }
    UA_Infer(ac->cx->dc, ac->cx, ts,
             L(other_emot_class1, other, NumberToObj(FloatAbs(weight)), E),
             in);
  }

  /* todo: Relate <a>'s emotion to <other>'s goal. */
}