Implementing a Fuzzy Boolean

Status
Not open for further replies.

Baljeet

Member
Jan 31, 2011
76
0
As promise in , here is an implementation of a Fuzzy Boolean.

In the previous tutorial, we looked at what fuzzy logic is. Now we need to write a formal definition of what a fuzzy bool should do so we can create an Fbool class. This is where we have to get very precise.

We need to define a few basic things: the methods and the properties of the class. The only major data element in an Fbool is the floating point value that represents a value between 0% and 100%. This means we need a double that will be limited to values between 0.0 and 1.0. We need to overload the following operators: !, &&, and ||. The overloaded operators have to work on Fbools as well as bools. We need to be able to cast an Fbool to a bool (generate a random float between 0.0 and 1.0... below the internal float returns true, else false).

Since we are dealing with random numbers, we MUST initialize the random number generator and keep track of whether it's been initialized (so we aren't reinitializing it repeatedly). Bools will be treated as 1.0 when true, 0.0 when false. Finally, we need a way to set or get the internal float while enforcing the restriction of being between 0.0 and 1.0.

All of this is represented in the header file below:

fbool.h
Code:
# ifndef FBOOL_DEFINED
# define FBOOL_DEFINED
class Fbool{
  static bool randomized;
  double probability;
public:
  void setval(double val);
  void setval(bool val);
  double getval() const;
  bool tobool() const;
  Fbool(double val);
  Fbool(bool val);
  Fbool();
  Fbool operator&&(Fbool);
  Fbool operator&&(bool);
  Fbool operator||(Fbool);
  Fbool operator||(bool);
  Fbool operator!();
};
Fbool operator&&(bool, Fbool);
Fbool operator||(bool, Fbool);
# endif
Notice that I've defined almost every possible way to use each operator. I did this on purpose because, for me, an explicit statement is clearer than defining the implicit conversions along with a few operator combinations. An obvious extension is defining && and || against floats.

The definitions are located in the file below:

fbool.cpp
Code:
#include <ctime>
#include <cstdlib>
#include "fbool.h"

bool Fbool::randomized=false;

void Fbool::setval(double val)
{
  if (val > 1.0) this->probability = 1.0;
  else if (val < 0.0) this-> probability = 0.0;
  else this->probability = val;
}

void Fbool::setval(bool val)
{
  if (val) this->probability = 1.0;
  else this-> probability = 0.0;
}

double Fbool::getval() const
{
  return this->probability;
}

bool Fbool::tobool() const
{
  return double(rand())/RAND_MAX <= this->probability;
}

Fbool::Fbool(double val)
{
  if (!randomized)
  {
    randomized = true;
    srand(time(0));
  }
  if (val > 1.0) this->probability = 1.0;
  else if (val < 0.0) this-> probability = 0.0;
  else this->probability = val;
}

Fbool::Fbool(bool val)
{
  if (!randomized)
  {
    randomized = true;
    srand(time(0));
  }
  if (val) this->probability = 1.0;
  else this-> probability = 0.0;
}

Fbool::Fbool()
{
  if (!randomized)
  {
    randomized = true;
    srand(time(0));
  }
  this-> probability = 0.0;
}

Fbool Fbool::operator&&(Fbool var)
{
  double temp;
  if (this->probability < var.probability)
    return Fbool(this->probability);
  else
    return Fbool(var.probability);
}

Fbool Fbool::operator&&(bool var)
{
  if (var)
    return Fbool(this->probability);
  else
    return Fbool(false);
}

Fbool Fbool::operator||(Fbool var)
{
  if (this->probability > var.probability)
    return Fbool(this->probability);
  else
    return Fbool(var.probability);
}

Fbool Fbool::operator||(bool var)
{
  if (var)
    return Fbool(true);
  else
    return Fbool(this->probability);
}

Fbool Fbool::operator!()
{
  return Fbool(1.0-this->probability);
}

Fbool operator&&(bool var1, Fbool var2)
{
  return var2&&var1;
}

Fbool operator||(bool var1, Fbool var2)
{
  return var2||var1;
}
An important detail when dealing with floats is that we MUST ensure that we handle values in a reasonable way. In this case, the setvalue() function must enforce keeping values within the range of 0.0 and 1.0. We also make sure that true corresponds with 1.0 and false with 0.0 so that everything remains consistent both with the previous definition and also integer conversions with booleans.

Finally, we have a quick test utility to demonstrate the behavior:

testfbool.cpp
Code:
#include <iostream>
#include "fbool.h"
using std::cout;

int main(int argc, char* argv[])
{
  Fbool mytestbool;
  cout<<"default value: "<<mytestbool.getval()<<"\n";
  int i;
  int pass=0, count=0;
  for(i=1;i<=100;i++)
  {
    count++;
    if (mytestbool.tobool()) pass++;
  }
  cout<<pass<<" of "<<count<<" were true\n";
  mytestbool.setval(true);
  pass=0;
  count=0;
  cout<<"true value: "<<mytestbool.getval()<<"\n";
  for(i=1;i<=100;i++)
  {
    count++;
    if (mytestbool.tobool()) pass++;
  }
  cout<<pass<<" of "<<count<<" were true\n";
  mytestbool.setval(0.75);
  pass=0;
  count=0;
  cout<<"0.75 value: "<<mytestbool.getval()<<"\n";
  for(i=1;i<=100;i++)
  {
    count++;
    if (mytestbool.tobool()) pass++;
  }
  cout<<pass<<" of "<<count<<" were true\n";
  mytestbool.setval(1.25);
  pass=0;
  count=0;
  cout<<"1.25 value: "<<mytestbool.getval()<<"\n";
  for(i=1;i<=100;i++)
  {
    count++;
    if (mytestbool.tobool()) pass++;
  }
  cout<<pass<<" of "<<count<<" were true\n";
  mytestbool.setval(0.25);
  pass=0;
  count=0;
  cout<<"0.25 value: "<<mytestbool.getval()<<"\n";
  for(i=1;i<=100;i++)
  {
    count++;
    if (mytestbool.tobool()) pass++;
  }
  cout<<pass<<" of "<<count<<" were true\n";
  mytestbool.setval(-1.25);
  pass=0;
  count=0;
  cout<<"-1.25 value: "<<mytestbool.getval()<<"\n";
  for(i=1;i<=100;i++)
  {
    count++;
    if (mytestbool.tobool()) pass++;
  }
  cout<<pass<<" of "<<count<<" were true\n";
  
  Fbool mytest2(0.25);
  mytestbool.setval(0.75);
  cout<<"mytestbool: "<<mytestbool.getval()<<"\n";
  cout<<"mytest2: "<<mytest2.getval()<<"\n";
  cout<<"mytestbool&&mytest2: "<<(mytestbool&&mytest2).getval()<<"\n";
  cout<<"mytestbool||mytest2: "<<(mytestbool||mytest2).getval()<<"\n";
  cout<<"mytestbool&&true: "<<(mytestbool&&true).getval()<<"\n";
  cout<<"mytestbool&&false: "<<(mytestbool&&false).getval()<<"\n";
  cout<<"mytestbool||true: "<<(mytestbool||true).getval()<<"\n";
  cout<<"mytestbool||false: "<<(mytestbool||false).getval()<<"\n";
  cout<<"!mytestbool: "<<(!mytestbool).getval()<<"\n";
  cout<<"!mytest2: "<<(!mytest2).getval()<<"\n";
}

Sample output from this is:
default value: 0
0 of 100 were true
true value: 1
100 of 100 were true
0.75 value: 0.75
77 of 100 were true
1.25 value: 1
100 of 100 were true
0.25 value: 0.25
23 of 100 were true
-1.25 value: 0
0 of 100 were true
mytestbool: 0.75
mytest2: 0.25
mytestbool&&mytest2: 0.25
mytestbool||mytest2: 0.75
mytestbool&&true: 0.75
mytestbool&&false: 0
mytestbool||true: 1
mytestbool||false: 0.75
!mytestbool: 0.25
!mytest2: 0.75

All Credits goes to one who really made this...
 
Status
Not open for further replies.

Users who are viewing this thread

Top