From: aldavi01@starbase.spd.louisville.edu (Arlie Davis)
Subject: How to solve problem with simulating logic gates with classes?
Organization: University of Louisville
Date: Sun, 26 Jul 1992 07:49:07 GMT

I'm trying to write a set of classes to simulate a network of logic gates,
using a base class Gate, with a single virtual member: "int evaluate (void)
const = 0".  The derived classes (NandGate, XorGate, etc...) have references
to their input objects ("const Gate& a;" in derived class).  There are
several "source" gates: IntGate (which is a wrapper for a const reference
to an integer) and InputGate (which calls a given function).

Everything works fine, everything works great, but only for simple logic
circuits, where "simple" means "no feedback".  No flip-flops, no memory
circuits at all.  Sure, I can declare a flip-flop, but only globally:

InputGate set;
InputGate reset;

extern NandGate set_gate;
extern NandGate reset_gate;

NandGate set_gate (set, reset_gate);
NandGate reset_gate (reset, set_gate);

However, any attempt to call evaluate for either of the above [re]set_gate
objects always results in the process dying with failed stack growth --
in other words, unbounded recursion.  :(

Has anyone written a base class for doing something similar?  Does a public
library have a decent implementation of this, that allows flip-flops and
circuits with self-reference?  (Am I reinventing the wheel?)

Any help is greatly appreciated.  If there is sufficient response, I'll
make a stab at a summary.  (Short) source code follows:

////// logic.h

class Gate {
  public:
  virtual int evaluate (void) const = 0;
  operator int (void) const { return evaluate(); }
  };

class AndGate : public Gate {
  const Gate& a;
  const Gate& b;

  public:
  AndGate (const Gate& aa, const Gate& bb) : a (aa), b (bb) {}
  virtual int evaluate (void) const;
  };

class OrGate : public Gate {
  const Gate& a;
  const Gate& b;

  public:
  OrGate (const Gate& aa, const Gate& bb) : a (aa), b (bb) {}
  virtual int evaluate (void) const;
  };

class NotGate : public Gate {
  const Gate& a;

  public:
  NotGate (const Gate& aa) : a (aa) {}
  virtual int evaluate (void) const;
  };

class NandGate : public Gate {
  const Gate& a;
  const Gate& b;

  public:
  NandGate (const Gate& aa, const Gate& bb) : a (aa), b (bb) {}
  virtual int evaluate (void) const;
  };

class NorGate : public Gate {
  const Gate& a;
  const Gate& b;

  public:
  NorGate (const Gate& aa, const Gate& bb) : a (aa), b (bb) {}
  virtual int evaluate (void) const;
  };

class InputGate : public Gate {
  int (*function) (void);
  public:
  InputGate (int (*f) (void)) : function (f) {}
  virtual int evaluate (void) const;
  };

class IntGate : public Gate {
  const int& i;
  public:
  IntGate (const int& ii) : i (ii) {}
  virtual int evaluate (void) const;
  };

////// logic.cc

#include "logic.h"

int AndGate::evaluate (void) const
  {
  if (!a.evaluate()) return 0;
  if (!b.evaluate()) return 0;
  return 1;
  }

int OrGate::evaluate (void) const
  {
  if (a.evaluate()) return 1;
  if (b.evaluate()) return 1;
  return 0;
  }

int NotGate::evaluate (void) const
  {
  return !a.evaluate();
  }

int NandGate::evaluate (void) const
  {
  if (!a.evaluate()) return 1;
  if (!b.evaluate()) return 1;
  return 0;
  }

int NorGate::evaluate (void) const
  {
  if (a.evaluate()) return 0;
  if (b.evaluate()) return 0;
  return 1;
  }

int InputGate::evaluate (void) const
  {
  return (*function)();
  }

int IntGate::evaluate (void) const
  {
  return i;
  }

////// end of example source

-- 
lrwx------   1 aldavi01 emacsstu       9 Jun  6 12:43 .signature -> /dev/null