wow

Sample code use

This is an illustration of how to apply the FLIP++ libraries. It should provide a knowledge engineer or programmer with the basics of the FLIP++ functionality when intending to include the libraries as part of a more specific system.

Although this example is quite simple, but it should be enough for a demonstration of the library. Suppose we have a heating system that is controlled by an indoor and outdoor temperature sensor. This gives us an idea of what to use for linguistic variables: heating, indoor and outdoor. Furthermore, we need a representation of the specific values that the linguistic variables can have. As we are using a fuzzy system it is rather straightforward to define these values called linguistic terms.


//
//     ------------------------------------
//      F L I P D E M O . C P P
//     ------------------------------------
//

#include "flip.h"

main() {
// *** declare and allocate io-streams

ifstream *input = new ifstream;
ofstream *output = new ofstream;

// *** declare errorstring

char static error[100]=" ";

A distinct name and colour must be defined for each linguistic term of the linguistic variables as shown in the following code sections. Therefore, a CList class instance is used for outdoor, heating and indoor with the parameter indicating the number of linguistic terms.

	CList *cl_outdoor  = new CList(4);
	CList *cl_indoor   = new CList(3);
	CList *cl_heating  = new CList(3);

Now, the same procedure is followed with the NList class in order to attach names to the linguistic terms.

	NList *nl_outdoor = new NList;
	NList *nl_indoor  = new NList;
	NList *nl_heating = new NList;

Having the objects instantiated, we can now assign the linguistic terms to the linguistic variables by putting them into the respective NList objects.

	nl_outdoor->add("icy");
	nl_outdoor->add("cool");
	nl_outdoor->add("mild");
	nl_outdoor->add("hot");
	nl_indoor->add("cold");
	nl_indoor->add("medium");
	nl_indoor->add("warm");
	nl_heating->add("no");
	nl_heating->add("half");
	nl_heating->add("full");

So far, we have dealt with the example only on a linguistic level. However, in order to get any results out of the system through the evaluation process we have to specify some parameters. Hence we introduce another object for each linguistic variable: the ParameterSet. It contains the values of the support range, median, dilatation, distribution and importance of each linguistic variable. Furthermore it includes the NList and CList objects defined above.

	ParameterSet *ps_outdoor,*ps_indoor,*ps_heating;
	ps_outdoor = new ParameterSet(
		"ps_outdoor", -50, 40, 0, 0.9, 0.7, 1, cl_outdoor, nl_outdoor);
	ps_indoor  = new ParameterSet(
		"ps_indoor", 0, 40, 15, 0.9, 0.7, 0.9, cl_indoor, nl_indoor);
	ps_heating = new ParameterSet(
		"ps_heating", 0, 100, 50, 0.9, 0.8, 1, cl_heating, nl_heating);

Thus far, we have only defined the parameters of the linguistic variables. But there are still no instances of the linguistic variables. The next step is to create a CombinedVariable (=linguistic variable) object for each linguistic variable. The ParameterSet is included in this variable.

	CombinedVariable *cv_outdoor = 
		new CombinedVariable(ps_outdoor,"outdoor");
	CombinedVariable *cv_indoor = 
		new CombinedVariable(ps_indoor,"indoor");
	CombinedVariable *cv_heating = 
		new CombinedVariable(ps_heating,"heating");

As the outdoor and indoor temperatures are received from a sensor, they are input variables. Therefore, it is necessary to attach values to them, which starts the matching process. The evaluation process then treats them as matched variables.

	cv_outdoor->set_value(7);
	cv_indoor->set_value(17);

With the linguistic variables defined, the next step is to define a set of rules that describes the relationship between the linguistic variables. We create an instance of the RuleSet class and specify the inference operator and attach the linguistic variables to it.

	RuleSet *rule_set = new RuleSet();
	rule_set->get_operator_set()->set_inference_operator(maximum);
	rule_set->get_ps_list()->add(ps_outdoor);
	rule_set->get_ps_list()->add(ps_indoor);
	rule_set->get_ps_list()->add(ps_heating);

The rules are simply added to the RuleSet with the add_ComplexRule method.

	rule_set->add_ComplexRule(
		cv_outdoor, "icy",  cv_indoor, "cold",
		cv_heating, "full", AND, 1);
	rule_set->add_ComplexRule(
		cv_outdoor, "icy",  cv_indoor, "medium",
		cv_heating, "full", AND, 0.9);
	rule_set->add_ComplexRule(
		cv_outdoor, "icy",  cv_indoor, "warm",
		cv_heating, "half", AND, 1);
	rule_set->add_ComplexRule(
		cv_outdoor, "cool",  cv_indoor, "cold",
		cv_heating, "full", AND, 0.8);
	rule_set->add_ComplexRule(
		cv_outdoor, "cool",  cv_indoor, "medium",
		cv_heating, "half", AND, 1);
	rule_set->add_ComplexRule(
		cv_outdoor, "cool",  cv_indoor, "warm",
		cv_heating, "half", AND, 0.7);
	rule_set->add_ComplexRule(
		cv_outdoor, "mild",  cv_indoor, "cold",
		cv_heating, "half", AND, 1);
	rule_set->add_ComplexRule(
		cv_outdoor, "mild",  cv_indoor, "medium",
		cv_heating, "half", AND, 0.8);

Now we can start the evaluation process of the output variable heating

	rule_set->evaluate(cv_heating);
if (strcmp(error," ")!=0) cout << endl << " ### error: " << error << endl;

In order to show the modularity of FLIP++ we write the created RuleSet to a file, then we create a new RuleSet with an additional linguistic variable for the fuel_flow and reload the old RuleSet. Finally, the two RuleSets are joined together and put into a more complicated RuleSet.

Below the RuleSet is written to a file.

	output->open("fliprule.dat");
	rule_set->write(output);
	output->close();

Here a new RuleSet is created.

	RuleSet *rule_set2 = new RuleSet();

As we want to use another linguistic variable for the fuel_flow, we must first build a CombinedVariable object and all part objects that are required. This follows the same scheme shown at the beginning.

	CList *cl_fuel_flow  = new CList(3);
	NList *nl_fuel_flow = new NList;
	nl_fuel_flow->add("zero");
	nl_fuel_flow->add("low");
	nl_fuel_flow->add("high");
	ParameterSet *ps_fuel_flow = new ParameterSet("ps_fuel_flow", 
		0, 50, 20, 0.9, 0.9, 1, cl_fuel_flow, nl_fuel_flow);
	rule_set2->get_ps_list()->add(ps_fuel_flow);
	CombinedVariable *cv_fuel_flow = 
		new CombinedVariable(ps_fuel_flow,"fuel_flow");
Below, we add new rules connecting the new variable to the existing ones. This is also the reason why we have not deleted the old RuleSet yet as we need it for the rule definitions.
	rule_set2->add_BasicRule( cv_heating, "no",   cv_fuel_flow, "zero", 1);
	rule_set2->add_BasicRule( cv_heating, "half", cv_fuel_flow, "low",  1);
	rule_set2->add_BasicRule( cv_heating, "full", cv_fuel_flow, "high", 1);
Now, we put the two RuleSets together. This is done by loading the old RuleSet and then adding it to the extended one.
	delete rule_set;
	RuleSet *rule_set_temp = new RuleSet();
	input->open("fliprule.dat");
	rule_set_temp->read(input);
	input->close();
	rule_set2->get_ps_list()->add(rule_set_temp->get_ps_list());
	rule_set2->get_cv_list()->add(rule_set_temp->get_cv_list());
	rule_set2->add_all_RuleBlocks(rule_set_temp);
	delete rule_set_temp;

The evaluation procedure for the fuel_flow variable can now be started as usual.

	rule_set2->evaluate(cv_fuel_flow);
	}; 



Back to DocuFLIP++ overview StarFLIP home page.

(c)1996 Andreas Raggl, Mazen Younes, Markus Bonner, Wolfgang Slany

Last modified: Tue Jun 24 15:41:03 MET-DST 1997 by StarFLIP Team