tags:

views:

82

answers:

3

Hi all!

I have a CognitiveEntity class, defined this way:

class CognitiveEntity : public Object
{
public:
  CognitiveEntity (FuzzyCognitiveMap fcm, SystemState s);
  ~CognitiveEntity ();

  template <typename T> void RegisterChange (std::string context, T value);

  bool operator!= (const CognitiveEntity& rhs) const;

private:
  FuzzyCognitiveMap m_fuzzyCognitiveMap;
  SystemState       m_systemState;

  std::vector <SystemState> RunFuzzyCognitiveMap ();
};

As shown, a CognitiveEntity has a SystemState object, which in turn has a vector of Concept objects (only the most relevant lines are shown):

class SystemState
{
public:
  SystemState ();
  ~SystemState ();

  void       AddConcept (Concept c) { m_L.push_back(c); }
  std::vector <Concept> m_L;
};

Inside the CognitiveEntity::RegisterChange, I mark a Concept as a potential cause (by calling Concept::IsPotentialCause (bool) which merely sets a private member with the value passed):

template <typename T>
void
CognitiveEntity::RegisterChange (std::string context, T value)
{
  std::string name = context.substr(context.find_last_of ("/") +1);
  int pos = m_systemState.FindConcept(name);
  if (pos > -1)
  {
    int intValue = value ? 1 : 0;
    m_systemState.m_L[pos].SetConceptValue (intValue, false);

    if (m_systemState.m_L[pos].CheckVariation ())
    {
      m_systemState.m_L[pos].IsPotentialCause (true); // Mark this concept as a potential cause

      for (int cause = 0; cause < m_systemState.GetSize (); cause++)
      {
        if ( (cause != pos) && (m_systemState.m_L[cause].MayBeCause ()))
        {
          m_fuzzyCognitiveMap.UpdateFuzzyCognitiveMapEntry (cause, pos, m_systemState);
          m_systemState.m_L[cause].IsPotentialCause (false);
        }
      }
    }
  }

}

What happens is that as soon as RegisterChange is called another time, the Concept that was marked as potential cause, is marked no more. I tried running gdb and I am sure that that member is not set elsewhere.

I'm not sure if this little information is enough for you to give me some hints about such a behavior (I didn't want to flood the post with the code of both SystemState and Concept classes).

Regards, Jir

A: 

If this was a multi-threaded system, I'd say it sounds like a classic case of shared, mutable state that wasn't properly synchronized.

If you don't have a multi-threaded situation, I'd say set a watch on that variable and see what changes it.

duffymo
Good advice! I found out that a copy of the object is modified, and not the original.
Jir
So vote it up and accept it.
duffymo
I can only accept it. Need 15 reputation points to vote it up, sorry :)
Jir
A: 

Apologies in advance if I'm telling you something you already know, but the best way to prepare an example for posting on a forum is to produce an example that can be compiled and run, with as little unnecessary detail as possible. Not only will this help people to help you, quite often stripping the example down to the bare essentials will actually solve the problem, because you'll take out an apparently innocent piece of code and it'll start working again.

Without seeing more of the code, it's hard to be certain about what the cause is. I'm suspicious that a lot of your methods are defined to take objects of class type by value; while it's not necessarily wrong per se, might it be that you're generating copies of objects where you aren't expecting to? For example, if you pass a CognitiveEntity into a function by value and modify it there, then the copy that's outside the function won't be changed.

Tim
That should be a comment, not an answer.
Georg Fritzsche
I realize you're perfectly right.I was a bit unsure about how/what to post.The problem is, the code extends a network simulator (ns-3) so I can't readily prepare a stripped down version. I'll start prepare one right away.Thanks for the suggestion!
Jir
Following your advice, I prepared a stripped-down version of the code, which, surprisingly, seems to work flawlessly.I am not sure about how to include the whole code here, so I uploaded an archive: http://www.filedropper.com/cognitiveentityIf you compile and run the code you'll see that the variable in question is not changed between two successive calls of the function.Now, I cannot think of any difference between the original code and this one.
Jir
That link just lands me at the file dropper website.
imaginaryboy
For some reason, they indeed "dropped" the file. However it's no longer needed: I found the problem source.
Jir
A: 

Turns out the problem lied in how the code was called from within the network simulator (the code was meant to be used in the "ns-3" network simulator).

So, the problem wasn't even in the code I posted, and yet you managed to help me find the solution: thanks to the suggestions you gave me, I prepared a standalone version of the code and I watched the variable.

The problem was how I was passing the object. Specifically, instead of passing around the object by reference (as I thought I was doing) I should have used smart pointers.

Thank you all for the great insights! (and sorry for the mess... next time I'll be more accurate!)

Jir