before and after ..

Sample code use

This is an illustration of how to apply the ConFLIP++ libraries. The following sample code is a by-product of the ConFLIP++ development process and should provide a good overview of how to apply the specific features of the librariers in an appropriate way. Furthermore, it is strongly recommended to study the code sections concurrent with the description of the ConFLIP++ libraries.

/*********************************************************************/
/* This file is a testing program; it shows all                      */
/* important features of ConFLIP++                                   */
/*********************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fstream.h>
#include "cflp_dyn.h"

conflip_error_t conflip_error;

/*********************************************************************/
/*   DEMO  : HOW TO USE ConFLIP++                                    */
/*********************************************************************/

int main (void)
{
  int i,j;
  cout<<endl<<"WELCOME TO DEMO1"<<endl<<endl;
  ifstream infile;
  ofstream outfile;

Initially, some predefined values are read from files: The ListOfTables, the ListOfSetsOfLingTerms and the ListOfParameterSets. So the system is initialized with default Tables for the operators, default linguistic terms, and default ParameterSets.

  /*********************************************************************/
  /* CREATE HELP-ARRAYS                                                */
  /*********************************************************************/
  ListOfTables corrs;
  ListOfSetsOfLingTerms lings;
  ListOfParameterSets paras;

  infile.open("df_lings.cfp",ios::in);
  if(infile.is_open())
  {
    if(!lings.read(infile))
      cout<<conflip_error.get_txt_eval()<<endl;
    infile.close();
  }
  infile.open("df_corr.cfp",ios::in);
  if(infile.is_open())
  {
    if(!corrs.read(infile))
      cout<<conflip_error.get_txt_eval()<<endl;
    infile.close();
  }
  infile.open("df_paras.cfp",ios::in);
  if(infile.is_open())
  {
    if(!paras.read(infile))
      cout<<conflip_error.get_txt_eval()<<endl;
    infile.close();
  }

  cout<<"corrs : "<<endl;
  corrs.show();
  cout<<"lings : "<<endl;
  lings.show();
  cout<<"paras : "<<endl;
  paras.show();

In this code section, we have shown how to create a new SetOfLingTerms and how to modify it using the associated Sled object. Afterwards, a new ParameterSet is created and both the ParameterSet and the SetOfLingTerms are attached to the lists defined above.

  
  /*********************************************************************/
  /* EDIT HELP-ARRAYS                                                  */
  /*********************************************************************/

  cout<<"EDIT HELP-ARRAYS"<<endl;

  static name new_vars1[MAX_LING_VARS]={ "EXCELLENT", "FINE", "OK", 
  "POOR", "MISERABLE" };

  SetOfLingTerms my_set;
  if(!my_set.set_name_of_set("my_fuzzy_set"))
    cout<<conflip_error.get_txt_eval()<<endl;
  for(i=0;i<5;i++)
    if(!my_set.add(new_vars1[i]))
      cout<<conflip_error.get_txt_eval()<<endl;
  my_set.show();
  SledForLingTerms my_set_sled=my_set;
  my_set_sled[2];
  cout<<my_set_sled()<<endl;
  strcpy(my_set_sled(),"GREAT");

  static char *temp="my_parameters";

  NList namelist;
  CList colorlist;
  colorlist.add(blue);
  colorlist.add(violet);
  ParameterSet my_ps(temp,0.2,0.3,0.4,0.5,1,1,&colorlist,&namelist);

  if(!lings.add(&my_set))
    cout<<conflip_error.get_txt_eval()<<endl;
  if(!paras.add(&my_ps))
    cout<<conflip_error.get_txt_eval()<<endl;

  cout<<"lings : "<<endl;
  lings.show();
  cout<<"paras : "<<endl;
  paras.show();

Now, we can proceed with putting the parts together to a SetOfConstraints object and a object respectively. Furthermore a ListOfInfos is created that will be used to store information about constraints.

  /*********************************************************************/
  /* CREATE ListOfInfos, SetOfConstraints and SetOfEvalConstraints    */
  /*********************************************************************/

  cout<<"CREATE SetOfConstraints"<<endl;

  ListOfInfos infos;
  SetOfConstraints consts;
  if(!consts.set("my_consts",
		 (TableCompare *)corrs.lookup(DEFAULT_COMP),
		 (TableConcat *)corrs.lookup(DEFAULT_CONC),
		 paras.lookup(DEFAULT_PARA)))
    cout<<conflip_error.get_txt_eval()<<endl;

  SetOfEvalConstraints evals;
  if(!evals.set("my_eval",
		 (TableConcat *)corrs.lookup(DEFAULT_CONC),
		 paras.lookup(DEFAULT_PARA)))
    cout<<conflip_error.get_txt_eval()<<endl;

In ConFlip++ each constraint carries some information which is explicitly stored in the Info objects. In our example, we use some constraints concerning chemical compatibilities, which are relevant for the process of steelmaking. For example, the first constraint means that the aluminium value (a detailed explanation of this value is not relevant for this documentation) should be smaller than 0.08. This is a typical ConstraintCompare. On the other hand, the ConstraintConcat is the concatenation of two other constraints and therefore implicitly generates a hierarchy of constraints. For instance, the alu_alu constraint is a concatenation of the alu1 and alu2 constraints. Moreover, it is possible to combine constraints with different dilatation types: the concatenation of a fuzzy and crisp constraint result in a mixed constraint as it is the case with the alus_ni1 constraint.

  /*********************************************************************/
  /* CREATE INFOS                                                      */
  /*********************************************************************/

  cout<<"CREATE Infos"<<endl;

  InfoCompare alu1;
  if(!alu1.set("alu-c1", 0.9, fuzzy, "", "alu", fuzzy, smaller, 0.08))
    cout<<conflip_error.get_txt_eval()<<endl;
  if(!infos.add(&alu1))
    cout<<conflip_error.get_txt_eval()<<endl;

  InfoCompare alu2;
  if(!alu2.set("alu-c2", 0.2, fuzzy, "", "alu",fuzzy, equal, 0.08))
    cout<<conflip_error.get_txt_eval()<<endl;
  if(!infos.add(&alu2))
    cout<<conflip_error.get_txt_eval()<<endl;

  InfoConcat alu_alu;
  if(!alu_alu.set("alu-alu", 0.9, fuzzy, "", alu1.get_name(),
  alu2.get_name(), c_and))
    cout<<conflip_error.get_txt_eval()<<endl;
  if(!infos.add(&alu_alu))
    cout<<conflip_error.get_txt_eval()<<endl;

  InfoCompare ni1;
  if(!ni1.set("ni-c1", 0.4, crisp, "", "ni", crisp, bigger, 0.4))
    cout<<conflip_error.get_txt_eval()<<endl;
  if(!infos.add(&ni1))
    cout<<conflip_error.get_txt_eval()<<endl;

  InfoCompare ni2;
  if(!ni2.set("ni-c2", 0.4, crisp, "", "ni", crisp, not_equal, 0.4))
    cout<<conflip_error.get_txt_eval()<<endl;
  if(!infos.add(&ni2))
    cout<<conflip_error.get_txt_eval()<<endl;

  InfoConcat ni_ni;
  if(!ni_ni.set("ni-ni", 0.23, crisp, "",
  ni1.get_name(),ni2.get_name(), c_or))
    cout<<conflip_error.get_txt_eval()<<endl;
  if(!infos.add(&ni_ni))
    cout<<conflip_error.get_txt_eval()<<endl;

  InfoConcat alus_ni1;
  if(!alus_ni1.set("alus-ni1", 0.3, mixed, "",
  alu_alu.get_name(),ni1.get_name(), c_and))
    cout<<conflip_error.get_txt_eval()<<endl;
  if(!infos.add(&alus_ni1))
    cout<<conflip_error.get_txt_eval()<<endl;

  InfoConcat alus_ni1_alu2;
  if(!alus_ni1_alu2.set("alus-ni1-alu2", 0.8, mixed, "",
  alus_ni1.get_name(), alu2.get_name(), c_and))
    cout<<conflip_error.get_txt_eval()<<endl;
  if(!infos.add(&alus_ni1_alu2))
    cout<<conflip_error.get_txt_eval()<<endl;

  cout<<"infos : "<<endl;
  infos.show();

With the infos created above it is now possible to fill the SetOfConstraints object with the constraints by using the Info objects. At this time also the rules that correspond to the constraint definitions are generated by using the corresponding Tables. The generation of rules is a part of the FLIP++ libraries.

  /*********************************************************************/
  /* PUT INFOS INTO SETOFCONSTRAINTS                                   */
  /*********************************************************************/

  cout<<"PUT INFOS INTO SetOfConstraints - create everything that does
  not exist"<<endl;
  ConstraintCompare hlpcomp;
  ConstraintConcat hlpconc;

  hlpcomp=(ConstraintCompare)ni1;
  if(!consts.add(&hlpcomp))
    cout<<conflip_error.get_txt_eval()<<endl;
  hlpcomp=(ConstraintCompare)alu1;
  if(!consts.add(&hlpcomp))
    cout<<conflip_error.get_txt_eval()<<endl;
  hlpcomp=(ConstraintCompare)alu2;
  if(!consts.add(&hlpcomp))
    cout<<conflip_error.get_txt_eval()<<endl;
  hlpconc=(ConstraintConcat)alu_alu;
  if(!consts.add(&hlpconc))
    cout<<conflip_error.get_txt_eval()<<endl;
  hlpcomp=(ConstraintCompare)ni2;
  if(!consts.add(&hlpcomp))
    cout<<conflip_error.get_txt_eval()<<endl;
  hlpconc=(ConstraintConcat)ni_ni;
  if(!consts.add(&hlpconc))
    cout<<conflip_error.get_txt_eval()<<endl;
  hlpconc=(ConstraintConcat)alus_ni1;
  if(!consts.add(&hlpconc))
    cout<<conflip_error.get_txt_eval()<<endl;
  hlpconc=(ConstraintConcat)alus_ni1_alu2;
  if(!consts.add(&hlpconc))
    cout<<conflip_error.get_txt_eval()<<endl;

  cout<<"consts : "<<endl;
  consts.show();
  RuleSet *rul_help1=consts.get_rules();
  rul_help1->show();

This code section shows how to modify a constraint or more specifically how to change its name and importance.

  /*********************************************************************/
  /* EDIT CONSTRAINTS                                                  */
  /*********************************************************************/

  cout<<"EDIT Constraints"<<endl;

  ConstraintCompare *coco;
  if((coco=(ConstraintCompare *)consts.lookup("alu-c1"))==NULL)
    cout<<conflip_error.get_txt_eval()<<endl;
  if(!coco->ConstraintCompare::set_name("ALUMINIUM"))
    cout<<conflip_error.get_txt_eval()<<endl;

  cout<<"consts : "<<endl;
  consts.show();

  if(!coco->set_importance (0.99))
    cout<<conflip_error.get_txt_eval()<<endl;

  ConstraintCompare *con;
  if((con=(ConstraintCompare *)consts.lookup("ALUMINIUM"))==NULL)
    cout<<conflip_error.get_txt_eval()<<endl;
  cout<<"new importance : "<< con->get_importance()<<endl;

Next comes the evaluation part. The constraint to be evalutated is the alus-ni1 constraint, which was defined above. Before the evaluation is started it is necessary to specify some input values. These input values are all the ConstraintCompares that are contained in the constraint tree of the constraint to be evaluated. The method get_lowest_level retrieves exactly these constraints for the specified constraint in a ListOfStrings object. Now, these linguistic variables can easily be set to a certain input value. After this, the evaluation can be started and the result is returned in a CombinedVariable. This result can then be stored in an EvalConstraint for further calculations. AnEvalConstraint can also be defuzzified or aggregated with other EvalConstraint. In our example, also the ni-ni constraint is evaluated and its result stored in an EvalConstraint. At the end, the two EvalConstraint are aggregated and an overall defuzzified result is calculated.

  /*********************************************************************/
  /* EVALUATE constraints to get CombinedVars, create EVALCONSTRAINTS  */
  /*********************************************************************/

  cout<<"EVALUATE"<<endl;

  ListOfStrings names_alus;
  SledForStrings mysled;
  consts.get_lowest_level("alus-ni1",names_alus);
  names_alus.show();
  mysled=names_alus;
  consts.set_value(mysled++,40.0);
  consts.set_value(mysled++,-70.0);
  consts.set_value(mysled++,80.0);

  CombinedVariable *sat_cv_alus= new CombinedVariable;
  sat_cv_alus = consts.evaluate("alus-ni1");
  
  sat_cv_alus->show();
  EvalConstraint ec1;
  if(!ec1.set("eval1",sat_cv_alus))
    cout<<conflip_error.get_txt_eval()<<endl;
  if(!evals.add(&ec1))
    cout<<conflip_error.get_txt_eval()<<endl;

  float s1=evals.defuzzify("eval1");
  cout<<"defuzzyfied value  for alus-ni1 :"<<s1<<endl;

  ListOfStrings names_ni;
  consts.get_lowest_level("ni-ni",names_ni);
  names_ni.show();
  mysled=names_ni;
  consts.set_value(mysled++,-20.0);
  consts.set_value(mysled++,50.0);
  CombinedVariable *sat_cv_ni = new CombinedVariable;
  sat_cv_ni=consts.evaluate("ni-ni");
  sat_cv_ni->show();

  EvalConstraint ec2;
  if(!ec2.set("eval2",sat_cv_ni))
    cout<<conflip_error.get_txt_eval()<<endl;
  if(!evals.add(&ec2))
    cout<<conflip_error.get_txt_eval()<<endl;

  float s3=evals.defuzzify("eval2");
  cout<<"defuzzyfied value  for ni-ni :"<<s3<<endl;

  cout<<"aggregate"<<endl;

  evals.aggregate("all", &ec1, &ec2);

  RuleSet* rul_help=evals.get_rules();
  rul_help->show();
  evals.show();

  float s2=evals.defuzzify("all");
  cout<<"defuzzyfied value for  all :"<<s2<<endl;

This code section simply shows how infos, constraints, and evaluated constraints are written in a file for later usage.

  /*********************************************************************/
  /* WRITE                                                             */
  /*********************************************************************/
 
  cout<<"WRITE"<<endl;

  outfile.open("t_infos.cfp",ios::out|ios::trunc);
  if(outfile.is_open())
  {
    if(!infos.write(outfile))
      cout<<conflip_error.get_txt_eval()<<endl;
    outfile.close();
  }
  outfile.open("t_consts.cfp",ios::out|ios::trunc);
  if(outfile.is_open())
  {
    if(!consts.write(outfile))
      cout<<conflip_error.get_txt_eval()<<endl;
    outfile.close();
  }
  outfile.open("t_evals.cfp",ios::out|ios::trunc);
  if(outfile.is_open())
  {
    if(!evals.write(outfile))
      cout<<conflip_error.get_txt_eval()<<endl;
    outfile.close();
  }

Kick_out methods are used to remove items from a list object, which is illustrated below.

  /*********************************************************************/
  /* KICK OUT                                                          */
  /*********************************************************************/

  cout<<"KICK OUT"<<endl;

  if(!infos.kick_out("alu-c1"))
  if(!consts.kick_out("ALUMINIUM"))
  if(!lings.kick_out("my_fuzzy_set"))

  cout<<"infos : "<<endl;
  infos.show ();
  cout<<"consts : "<<endl;
  consts.show();
  cout<<"lings : "<<endl;
  lings.show();

Similarly the write methods and the read methods are used to retrieve previously used and calculated data from files.

  /*********************************************************************/
  /* READ                                                              */
  /*********************************************************************/

  cout<<"READ"<<endl;

  ListOfInfos new_infos;
  SetOfConstraints new_consts;
  SetOfEvalConstraints new_evals;

  infile.open("t_infos.cfp",ios::in);
  if(infile.is_open())
  {
    if(!new_infos.read(infile))
      cout<<conflip_error.get_txt_eval()<<endl;
    infile.close();
  }
  infile.open("t_consts.cfp",ios::in);
  if(infile.is_open())
  {
    if(!new_consts.read(infile))
      cout<<conflip_error.get_txt_eval()<<endl;
    infile.close();
  }
  infile.open("t_evals.cfp",ios::in);
  if(infile.is_open())
  {
    if(!new_evals.read(infile))
      cout<<conflip_error.get_txt_eval()<<endl;
    infile.close();
  }

  cout<<"new infos : "<<endl;
  new_infos.show ();
  cout<<"new consts : "<<endl;
  new_consts.show();
  cout<<"new evals : "<<endl;
  new_evals.show();

Finally, the just read data is used to retrieve some objects from it. This demonstrates the flexibility of ConFLIP++ as far as reusing already built or calcualted structures for new computations are concerned.

  /*********************************************************************/
  /* FINAL TEST                                                        */
  /*********************************************************************/

  cout<<"FINAL TEST"<<endl;

  InfoCompare *c1=(InfoCompare *)new_infos.lookup("alu-c2");
  if(c1!=NULL)
    cout<<"1. name: "<<c1->get_name()<<"    dil: "
      <<(int)c1->get_dilatation()<<endl;

  ConstraintCompare *co=(ConstraintCompare *)new_consts.lookup("ni-c1");
  if(co!=NULL)
    cout<<"2. name: "<<co->get_name()<<"    var: "
      <<co->get_var_name()<< "   dil : " <<(int)co->get_dilatation()
      <<endl;

  ConstraintConcat *cc=(ConstraintConcat *)new_consts.lookup("alu-alu");
  if(cc!=NULL)
    cout<<"3. name: "<<cc->get_name()<<"     1.const: "
      <<cc->get_const1()<<"  dil: "<<(int)cc->get_dilatation()<<endl;

  ConstraintConcat *cc1=(ConstraintConcat *)new_consts.lookup("alus-ni1");
  if(cc1!=NULL)
    cout<<"4. name: "<<cc1->get_name()<<"    1.const: "
      <<cc1->get_const1()<<"  dil: "<<(int)cc1->get_dilatation()<<endl;

  /*********************************************************************/
  /* END                                                               */
  /*********************************************************************/

  cout<<endl<<"DEMO1 SUCCESSFULLY RUN - thank you, see you"<<endl;

  /*********************************************************************/  
  /* CLEAN-UP                                                          */
  /*********************************************************************/

  return(1);
}



Back to DocuFLIP++ overview StarFLIP home page
(c)1996 Andreas RAGGL, Mazen YOUNES, Markus BONNER, Wolfgang SLANY

Last modified: Tue Jun 24 15:35:29 MET-DST 1997 by StarFLIP Team