## A Look at Fuzzy Logic

### Crisp or Fuzzy Logic?

Logic deals with true and false. A proposition can be true on one occasion and false on another. “Apple is a red fruit” is such a proposition. If you are holding a Granny Smith apple that is green, the proposition that apple is a red fruit is false. On the other hand, if your apple is of a red delicious variety, it is a red fruit and the proposition in reference is true. If a proposition is true, it has a truth value of 1; if it is false, its truth value is 0. These are the only possible truth values. Propositions can be combined to generate other propositions, by means of logical operations.

When you say it will rain today or that you will have an outdoor picnic today, you are making statements with certainty. Of course your statements in this case can be either true or false. The truth values of your statements can be only 1, or 0. Your statements then can be said to be crisp.

On the other hand, there are statements you cannot make with such certainty. You may be saying that you think it will rain today. If pressed further, you may be able to say with a degree of certainty in your statement that it will rain today. Your level of certainty, however, is about 0.8, rather than 1. This type of situation is what fuzzy logic was developed to model. Fuzzy logic deals with propositions that can be true to a certain degree—somewhere from 0 to 1. Therefore, a proposition’s truth value indicates the degree of certainty about which the proposition is true. The degree of certainity sounds like a probability (perhaps subjective probability), but it is not quite the same. Probabilities for mutually exclusive events cannot add up to more than 1, but their fuzzy values may. Suppose that the probability of a cup of coffee being hot is 0.8 and the probability of the cup of coffee being cold is 0.2. These probabilities must add up to 1.0. Fuzzy values do not need to add up to 1.0. The truth value of a proposition that a cup of coffee is hot is 0.8. The truth value of a proposition that the cup of coffee is cold can be 0.5. There is no restriction on what these truth values must add up to.

### Fuzzy Sets

Fuzzy logic is best understood in the context of set membership. Suppose you are assembling a set of rainy days. Would you put today in the set? When you deal only with crisp statements that are either true or false, your inclusion of today in the set of rainy days is based on certainty. When dealing with fuzzy logic, you would include today in the set of rainy days via an ordered pair, such as (today, 0.8). The first member in such an ordered pair is a candidate for inclusion in the set, and the second member is a value between 0 and 1, inclusive, called the degree of membership in the set. The inclusion of the degree of membership in the set makes it convenient for developers to come up with a set theory based on fuzzy logic, just as regular set theory is developed. Fuzzy sets are sets in which members are presented as ordered pairs that include information on degree of membership. A traditional set of, say, k elements, is a special case of a fuzzy set, where each of those k elements has 1 for the degree of membership, and every other element in the universal set has a degree of membership 0, for which reason you don’t bother to list it.

### Fuzzy Set Operations

The usual operations you can perform on ordinary sets are union, in which you take all the elements that are in one set or the other; and intersection, in which you take the elements that are in both sets. In the case of fuzzy sets, taking a union is finding the degree of membership that an element should have in the new fuzzy set, which is the union of two fuzzy sets.

If a, b, c, and d are such that their degrees of membership in the fuzzy set A are 0.9, 0.4, 0.5, and 0, respectively, then the fuzzy set A is given by the fit vector (0.9, 0.4, 0.5, 0). The components of this fit vector are called fit values of a, b, c, and d.

#### Union of Fuzzy Sets

Consider a union of two traditional sets and an element that belongs to only one of those sets. Earlier you saw that if you treat these sets as fuzzy sets, this element has a degree of membership of 1 in one case and 0 in the other since it belongs to one set and not the other. Yet you are going to put this element in the union. The criterion you use in this action has to do with degrees of membership. You need to look at the two degrees of membership, namely, 0 and 1, and pick the higher value of the two, namely, 1. In other words, what you want for the degree of membership of an element when listed in the union of two fuzzy sets, is the maximum value of its degrees of membership within the two fuzzy sets forming a union.

If a, b, c, and d have the respective degrees of membership in fuzzy sets A, B as A = (0.9, 0.4, 0.5, 0) and B = (0.7, 0.6, 0.3, 0.8), then A [cup] B = (0.9, 0.6, 0.5, 0.8).

#### Intersection and Complement of Two Fuzzy Sets

Analogously, the degree of membership of an element in the intersection of two fuzzy sets is the minimum, or the smaller value of its degree of membership individually in the two sets forming the intersection. For example, if today has 0.8 for degree of membership in the set of rainy days and 0.5 for degree of membership in the set of days of work completion, then today belongs to the set of rainy days on which work is completed to a degree of 0.5, the smaller of 0.5 and 0.8.

Recall the fuzzy sets A and B in the previous example. A = (0.9, 0.4, 0.5, 0) and B = (0.7, 0.6, 0.3, 0.8). A[cap]B, which is the intersection of the fuzzy sets A and B, is obtained by taking, in each component, the smaller of the values found in that component in A and in B. Thus A[cap]B = (0.7, 0.4, 0.3, 0).

The idea of a universal set is implicit in dealing with traditional sets. For example, if you talk of the set of married persons, the universal set is the set of all persons. Every other set you consider in that context is a subset of the universal set. We bring up this matter of universal set because when you make the complement of a traditional set A, you need to put in every element in the universal set that is not in A. The complement of a fuzzy set, however, is obtained as follows. In the case of fuzzy sets, if the degree of membership is 0.8 for a member, then that member is not in that set to a degree of 1.0 – 0.8 = 0.2. So you can set the degree of membership in the complement fuzzy set to the complement with respect to 1. If we return to the scenario of having a degree of 0.8 in the set of rainy days, then today has to have 0.2 membership degree in the set of nonrainy or clear days.

Continuing with our example of fuzzy sets A and B, and denoting the complement of A by A’, we have A’ = (0.1, 0.6, 0.5, 1) and B’ = (0.3, 0.4, 0.7, 0.2). Note that A’ [cup] B’ = (0.3, 0.6, 0.7, 1), which is also the complement of A [cap] B. You can similarly verify that the complement of A [cup] B is the same as A’ [cap] B’. Furthermore, A [cup] A’ = (0.9, 0.6, 0.5, 1) and A [cap] A’ = (0.1, 0.4, 0.5, 0), which is not a vector of zeros only, as would be the case in conventional sets. In fact, A and A’ will be equal in the sense that their fit vectors are the same, if each component in the fit vector is equal to 0.5.

### Applications of Fuzzy Logic

Applications of fuzzy sets and fuzzy logic are found in many fields, including artificial intelligence, engineering, computer science, operations research, robotics, and pattern recognition. These fields are also ripe for applications for neural networks. So it seems natural that fuzziness should be introduced in neural networks themselves. Any area where humans need to indulge in making decisions, fuzzy sets can find a place, since information on which decisions are to be based may not always be complete and the reliability of the supposed values of the underlying parameters is not always certain.

#### Examples of Fuzzy Logic

Let us say five tasks have to be performed in a given period of time, and each task requires one person dedicated to it. Suppose there are six people capable of doing these tasks. As you have more than enough people, there is no problem in scheduling this work and getting it done. Of course who gets assigned to which task depends on some criterion, such as total time for completion, on which some optimization can be done. But suppose these six people are not necessarily available during the particular period of time in question. Suddenly, the equation is seen in less than crisp terms. The availability of the people is fuzzy-valued. Here is an example of an assignment problem where fuzzy sets can be used.

#### Commercial Applications

Many commercial uses of fuzzy logic exist today. A few examples are listed here:

A subway in Sendai, Japan uses a fuzzy controller to control a subway car. This controller has outperformed human and conventional controllers in giving a smooth ride to passengers in all terrain and external conditions.

Cameras and camcorders use fuzzy logic to adjust autofocus mechanisms and to cancel the jitter caused by a shaking hand.

Some automobiles use fuzzy logic for different control applications. Nissan has patents on fuzzy logic braking systems, transmission controls, and fuel injectors. GM uses a fuzzy transmission system in its Saturn vehicles.

FuziWare has developed and patented a fuzzy spreadsheet called FuziCalc that allows users to incorporate fuzziness in their data.

Software applications to search and match images for certain pixel regions of interest have been developed. Avian Systems has a software package called FullPixelSearch.

A stock market charting and research tool called SuperCharts from Omega Research, uses fuzzy logic in one of its modules to determine whether the market is bullish, bearish, or neutral.

### Fuzziness in Neural Networks

There are a number of ways fuzzy logic can be used with neural networks. Perhaps the simplest way is to use a fuzzifier function to preprocess or post-process data for a neural network. This is shown in figure:

A neural network with fuzzy preprocessor.

where a neural network has a preprocessing fuzzifier that converts data into fuzzy data for application to a neural network.

Let us build a simple fuzzifier based on an application to predict the direction of the stock market. Suppose that you wish to fuzzify one set of data used in the network, the Federal Reserve’s fiscal policy, in one of four fuzzy categories: very accommodative, accommodative, tight, or very tight. Let us suppose that the raw data that we need to fuzzify is the discount rate and the interest rate that the Federal Reserve controls to set the fiscal policy. Now, a low discount rate usually indicates a loose fiscal policy, but this depends not only on the observer, but also on the political climate. There is a probability, for a given discount rate that you will find two people who offer different categories for the Fed fiscal policy. Hence, it is appropriate to fuzzify the data, so that the data we present to the neural network is like what an observer would see.

Figure:

Fuzzy categories for Federal Reserve policy based on the Fed discount rate.

shows the fuzzy categories for different interest rates. Note that the category tight has the largest range. At any given interest rate level, you could have one possible category or several. If only one interest rate is present on the graph, this indicates that membership in that fuzzy set is 1.0. If you have three possible fuzzy sets, there is a requirement that membership add up to 1.0. For an interest rate of 8%, you have some chance of finding this in the tight category or the accommodative category. To find out the percentage probability from the graph, take the height of each curve at a given interest rate and normalize this to a one-unit length. At 8%, the tight category is about 0.8 unit in height, and accommodative is about 0.3 unit in height. The total is about 1.1 units, and the probability of the value being tight is then 0.8/1.1 = 0.73, while the probability of the value being accommodative is 0.27.

### Code for the Fuzzifier

Let’s develop C++ code to create a simple fuzzifier. A class called category is defined in listing:

fuzzfier.h

`// fuzzfier.h V. Rao, H. Rao`
`// program to fuzzify data`
` `
`class category`
`{`
`private:`
`     char name[30];`
`     float   lowval,highval,midval;`
` `
`public:`
`     category(){};`
`     void setname(char *);`
`     char * getname();`
`     void setval(float&,float&,float&);`
`     float getlowval();`
`     float getmidval();`
`     float gethighval();`
` `
`     float getshare(const float&);`
` `
`     ~category(){};`
` `
`};`
` `
`int randnum(int);`

Let’s look at the implementation file in listing:

fuzzfier.cpp

`// fuzzfier.cpp      V. Rao, H. Rao`
`// program to fuzzify data`
` `
`#include <iostream.h>`
`#include <stdlib.h>`
`#include <time.h>`
`#include <string.h>`
`#include <fuzzfier.h>`
` `
`void category::setname(char *n){`
`strcpy(name,n);`
`}`
` `
`char * category::getname(){`
`return name;`
`}`
` `
`void category::setval(float &h, float &m, float &l){`
`highval=h;`
`midval=m;`
`lowval=l;`
`}`
` `
`float category::getlowval(){`
`return lowval;`
`}`
` `
`float category::getmidval(){`
`return midval;`
`}`
` `
`float category::gethighval(){`
`return highval;`
`}`
` `
`float category::getshare(const float & input){`
`// this member function returns the relative membership`
`// of an input in a category, with a maximum of 1.0`
` `
`float output;`
`float midlow, highmid;`
` `
`midlow=midval-lowval;`
`highmid=highval-midval;`
` `
`// if outside the range, then output=0`
`if ((input <= lowval) || (input >= highval))`
`     output=0;`
` `
`else`
`     {`
` `
`     if (input > midval)`
` `
`          output=(highval-input)/highmid;`
` `
`     else`
` `
`     if (input==midval)`
` `
`          output=1.0;`
` `
`     else`
` `
`          output=(input-lowval)/midlow;`
` `
`     }`
`return output;`
` `
`}`
` `
`int randomnum(int maxval)`
`{`
`// random number generator`
`// will return an integer up to maxval`
` `
`srand ((unsigned)time(NULL));`
`return rand() % maxval;`
`}`
` `
`void main()`
`{`
`// a fuzzifier program that takes category information:`
`// lowval, midval and highval and category name`
`// and fuzzifies an input based on`
`// the total number of categories and the membership`
`// in each category`
` `
`int i=0,j=0,numcat=0,randnum;`
`float l,m,h, inval=1.0;`
` `
`char input[30]="               ";`
`category * ptr[10];`
`float relprob[10];`
`float total=0, runtotal=0;`
` `
`//input the category information; terminate with `done';`
` `
`while (1) {`
`     cout << "\nPlease type in a category name, e.g. Cool\n";`
`     cout << "Enter one word without spaces\n";`
`     cout << "When you are done, type `done' :\n\n";`
`     ptr[i]= new category;`
`     cin >> input;`
`     if ((input[0]=='d' && input[1]=='o' &&`
`             input[2]=='n' && input[3]=='e')) break;`
` `
`     ptr[i]->setname(input);`
` `
`     cout << "\nType in the lowval, midval and highval\n";`
`     cout << "for each category, separated by spaces\n";`
`     cout << " e.g. 1.0 3.0 5.0 :\n\n";`
` `
`     cin >> l >> m >> h;`
`     ptr[i]->setval(h,m,l);`
` `
`     i++;`
` `
`     }`
` `
`numcat=i; // number of categories`
` `
`// Categories set up: Now input the data to fuzzify`
`cout <<"\n\n";`
`cout << "===================================\n";`
`cout << "==Fuzzifier is ready for data==\n";`
`cout << "===================================\n";`
` `
`while (1)`
` `
`     {`
`     cout << "\ninput a data value, type 0 to terminate\n";`
` `
`     cin >> inval;`
` `
`     if (inval == 0) break;`
` `
`     // calculate relative probabilities of`
`     //   input being in each category`
` `
`     total=0;`
`     for (j=0;j<numcat;j++)`
`          {`
`          relprob[j]=100*ptr[j]->getshare(inval);`
`          total+=relprob[j];`
`          }`
` `
`     if (total==0)`
`          {`
`          cout << "data out of range\n";`
`          exit(1);`
`          }`
` `
`     randnum=randomnum((int)total);`
` `
`     j=0;`
`     runtotal=relprob[0];`
` `
`     while ((runtotal<randnum)&&(j<numcat))`
`          {`
`          j++;`
`          runtotal += relprob[j];`
`          }`
` `
`     cout << "\nOutput fuzzy category is ==> " <<`
`          ptr[j]->getname()<<"<== \n";`
` `
`          cout <<"category\t"<<"membership\n";`
`          cout <<"---------------\n";`
` `
`     for (j=0;j<numcat;j++)`
`          {`
`          cout << ptr[j]->getname()<<"\t\t"<<`
`               (relprob[j]/total) <<"\n";`
`          }`
` `
`     }`
`cout << "\n\nAll done. Have a fuzzy day !\n";`
`}`

There are three private data members called lowval, midval, and highval. These represent the values on the graph that define the category triangle. In the tight category, the lowval is 5.0, the midval is 8.5, and the highval is 12.0. The category class allows you to instantiate a category object and assign parameters to it to define it. Also, there is a string called name that identifies the category, e.g. “tight.” Various member functions are used to interface to the private data members. There is setval(), for example, which lets you set the value of the three parameters, while gethighval() returns the value of the parameter highval. The function getshare() returns the relative value of membership in a category given an input. In the example discussed earlier, with the number 8.0 as the Fed discount rate and the category tight defined according to the graph in Figure Fuzzy categories for Federal Reserve policy based on the Fed discount rate., getshare() would return 0.8. Note that this is not yet normalized. Following this example, the getshare() value from the accommodative category would also be used to determine the membership weights. These weights define a probability in a given category. A random number generator is used to define a value that is used to select a fuzzy category based on the probabilities defined.

This program first sets up all the categories you define. These could be for the example we choose or any example you can think of. After the categories are defined, you can start entering data to be fuzzified. As you enter data you see the probability aspect come into play. If you enter the same value twice, you may end up with different categories! You will see sample output shortly, but first a technical note on how the weighted probabilities are set up. The best way to explain it is with an example. Suppose that you have defined three categories, A, B, and C. Suppose that category A has a relative membership of 0.8, category B of 0.4, and category C of 0.2. In the program, these numbers are first multiplied by 100, so you end up with A=80, B=40, and C=20. Now these are stored in a vector with an index j initialized to point to the first category. Let’s say that these three numbers represent three adjacent number bins that are joined together. Now pick a random number to index into the bin that has its maximum value of (80+40+20). If the number is 100, then it is greater than 80 and less than (80+40), you end up in the second bin that represents B. Does this scheme give you weighted probabilities? Yes it does, since the size of the bin (given a uniform distribution of random indexes into it) determines the probability of falling into the bin. Therefore, the probability of falling into bin A is 80/(80+40+20).

Sample output from the program is shown below. Our input is in italic; computer output is not. The categories defined by the graph in Figure Fuzzy categories for Federal Reserve policy based on the Fed discount rate. are entered in this example. Once the categories are set up, the first data entry of 4.0 gets fuzzified to the accommodative category. Note that the memberships are also presented in each category. The same value is entered again, and this time it gets fuzzified to the very accommodative category. For the last data entry of 12.5, you see that only the very tight category holds membership for this value. In all cases you will note that the memberships add up to 1.0.

` fuzzfier`
` `
`Please type in a category name, e.g. Cool`
`Enter one word without spaces`
`When you are done, type `done' :`
` `
`v.accommodative`
` `
`Type in the lowval, midval and highval`
`for each category, separated by spaces`
` e.g. 1.0 3.0 5.0 :`
` `
`0 3 6`
` `
`Please type in a category name, e.g. Cool`
`Enter one word without spaces`
`When you are done, type `done' :`
` `
`accommodative`
` `
`Type in the lowval, midval and highval`
`for each category, separated by spaces`
` e.g. 1.0 3.0 5.0 :`
` `
`3 6 9`
` `
`Please type in a category name, e.g. Cool`
`Enter one word without spaces`
`When you are done, type `done' :`
` `
`tight`
` `
`Type in the lowval, midval and highval`
`for each category, separated by spaces`
` e.g. 1.0 3.0 5.0 :`
` `
`5 8.5 12`
` `
`Please type in a category name, e.g. Cool`
`Enter one word without spaces`
`When you are done, type `done' :`
` `
`v.tight`
` `
`Type in the lowval, midval and highval`
`for each category, separated by spaces`
` e.g. 1.0 3.0 5.0 :`
` `
`10 12 14`
` `
`Please type in a category name, e.g. Cool`
`Enter one word without spaces`
`When you are done, type `done' :`
` `
`done`
` `
`===================================`
`==Fuzzifier is ready for data==`
`===================================`
` `
`input a data value, type 0 to terminate`
`4.0`
` `
`Output fuzzy category is ==> accommodative<==`
`category   membership`
`-----------------------------`
`v.accommodative      0.666667`
`accommodative        0.333333`
`tight        0`
`v.tight      0`
` `
`input a data value, type 0 to terminate`
`4.0`
` `
`Output fuzzy category is ==> v.accommodative<==`
`category   membership`
`-----------------------------`
`v.accommodative      0.666667`
`accommodative        0.333333`
`tight        0`
`v.tight      0`
` `
`input a data value, type 0 to terminate`
`7.5`
` `
`Output fuzzy category is ==> accommodative<==`
`category   membership`
`-----------------------------`
`v.accommodative      0`
`accommodative        0.411765`
`tight        0.588235`
`v.tight      0`
` `
`input a data value, type 0 to terminate`
`11.0`
` `
`       Output fuzzy category is ==> tight<==`
`category   membership`
`-----------------------------`
`v.accommodative      0`
`accommodative        0`
`tight        0.363636`
`v.tight      0.636364`
` `
`input a data value, type 0 to terminate`
`12.5`
` `
`Output fuzzy category is ==> v.tight<==`
`category   membership`
`-----------------------------`
`v.accommodative      0`
`accommodative        0`
`tight        0`
`v.tight      1`
` `
`input a data value, type 0 to terminate`
`0`
`All done. Have a fuzzy day !`

### Fuzzy Control Systems

The most widespread use of fuzzy logic today is in fuzzy control applications. You can use fuzzy logic to make your air conditioner cool your room. Or you can design a subway system to use fuzzy logic to control the braking system for smooth and accurate stops. A control system is a closed-loop system that typically controls a machine to achieve a particular desired response, given a number of environmental inputs. A fuzzy control system is a closed-loop system that uses the process of fuzzification, as shown in the Federal Reserve policy program example, to generate fuzzy inputs to an inference engine, which is a knowledge base of actions to take. The inverse process, called defuzzification, is also used in a fuzzy control system to create crisp, real values to apply to the machine or process under control. In Japan, fuzzy controllers have been used to control many machines, including washing machines and camcorders.

Figure:

Diagram of a fuzzy control system.

shows a diagram of a fuzzy control system. The major parts of this closed-loop system are:

machine under control—this is the machine or process that you are controlling, for example, a washing machine

outputs—these are the measured response behaviors of your machine, for example, the temperature of the water

fuzzy outputs—these are the same outputs passed through a fuzzifier, for example, hot or very cold

inference engine/fuzzy rule base—an inference engine converts fuzzy outputs to actions to take by accessing fuzzy rules in a fuzzy rule base. An example of a fuzzy rule: IF the output is very cold, THEN increase the water temperature setting by a very large amount

fuzzy inputs—these are the fuzzy actions to perform, such as increase the water temperature setting by a very large amount

inputs—these are the (crisp) dials on the machine to control its behavior, for example, water temperature setting = 3.423, converted from fuzzy inputs with a defuzzifier

The key to development of a fuzzy control system is to iteratively construct a fuzzy rule base that yields the desired response from your machine. You construct these fuzzy rules from knowledge about the problem. In many cases this is very intuitive and gives you a robust control system in a very short amount of time.

### Fuzziness in Neural Networks

Fuzziness can enter neural networks to define the weights from fuzzy sets. A comparison between expert systems and fuzzy systems is important to understand in the context of neural networks. Expert systems are based on crisp rules. Such crisp rules may not always be available. Expert systems have to consider an exhaustive set of possibilities. Such sets may not be known beforehand. When crisp rules are not possible, and when it is not known if the possibilities are exhaustive, the expert systems approach is not a good one.

Some neural networks, through the features of training and learning, can function in the presence of unexpected situations. Therein neural networks have an advantage over expert systems, and they can manage with far less information than expert systems need.

One form of fuzziness in neural networks is called a fuzzy cognitive map. A fuzzy cognitive map is like a dynamic state machine with fuzzy states. A traditional state machine is a machine with defined states and outputs associated with each state. Transitions from state to state take place according to input events or stimuli. A fuzzy cognitive map looks like a state machine but has fuzzy states (not just 1 or 0). You have a set of weights along each transition path, and these weights can be learned from a set of training data.

### Neural-Trained Fuzzy Systems

So far we have considered how fuzzy logic plays a role in neural networks. The converse relationship, neural networks in fuzzy systems, is also an active area of research. In order to build a fuzzy system, you must have a set of membership rules for fuzzy categories. It is sometimes difficult to deduce these membership rules with a given set of complex data. Why not use a neural network to define the fuzzy rules for you? A neural network is good at discovering relationships and patterns in data and can be used to preprocess data in a fuzzy system. Further, a neural network that can learn new relationships with new input data can be used to refine fuzzy rules to create a fuzzy adaptive system. Neural trained fuzzy systems are being used in many commercial applications, especially in Japan:

The Laboratory for International Fuzzy Engineering Research (LIFE) in Yokohama, Japan has a backpropagation neural network that derives fuzzy rules and membership functions. The LIFE system has been successfully applied to a foreign-exchange trade support system with approximately 5000 fuzzy rules.

Ford Motor Company has developed trainable fuzzy systems for automobile idle-speed control.

National Semiconductor Corporation has a software product called NeuFuz that supports the generation of fuzzy rules with a neural network for control applications.

A number of Japanese consumer and industrial products use neural networks with fuzzy systems, including vacuum cleaners, rice cookers, washing machines, and photocopying machines.

AEG Corporation of Germany uses a neural-network-trained fuzzy control system for its water- and energy-conserving washing machine. After the machine is loaded with laundry, it measures the water level with a pressure sensor and infers the amount of laundry in the machine by the speed and volume of water. A total of 157 rules were generated by a neural network that was trained on data correlating the amount of laundry with the measurement of water level on the sensor.

### Summary

In this chapter, you read about fuzzy logic, fuzzy sets, and simple operations on fuzzy sets. Fuzzy logic, unlike Boolean logic, has more than two on or off categories to describe behavior of systems. You use membership values for data in fuzzy categories, which may overlap. In this chapter, you also developed a fuzzifier program in C++ that takes crisp values and converts them to fuzzy values, based on categories and memberships that you define. For use with neural networks, fuzzy logic can serve as a post-processing or pre-processing filter. Kosko developed neural networks that use fuzziness and called them fuzzy associative memories, which will be discussed in later chapters. You also read about how neural networks can be used in fuzzy systems to define membership functions and fuzzy rules.