/****************************************************************************
 * This file was derived from the CNCL library by the Pablo research group.
 *
 * The complete CNCL library is available at:
 *       http://www.comnets.rwth-aachen.de/doc/cncl.html
 *
 * The CNCL copyright notice is included here:
 *
 * |_|_|_  |_|_    |_    |_|_|_  |_               C O M M U N I C A T I O N
 *|_       |_  |_  |_  |_        |_                         N E T W O R K S
 *|_       |_  |_  |_  |_        |_                               C L A S S
 * |_|_|_  |_    |_|_    |_|_|_  |_|_|_|_                     L I B R A R Y
 *
 *
 *
 * Copyright (C) 1992-1998   Communication Networks
 *                           Aachen University of Technology
 *                           D-52056 Aachen
 *                           Germany
 *                           Email: cncl-adm@comnets.rwth-aachen.de
 *
 *
 * This library is free  software; you can  redistribute it and/or modify
 * it  under   the terms  of the GNU   Library  General Public License as
 * published by the  Free Software Foundation;  either  version 2 of  the
 * License, or  (at  your option)  any  later  version.  This  library is
 * distributed  in the  hope  that  it  will  be useful,  but WITHOUT ANY
 * WARRANTY;  without even the   implied  warranty of MERCHANTABILITY  or
 * FITNESS FOR A PARTICULAR PURPOSE.   See the GNU Library General Public
 * Library General Public License along with  this library; if not, write
 * to the Free Software Foundation,  675  Mass Ave, Cambridge, MA  02139,
 * USA.
 ****************************************************************************/

//   -*- C++ -*-
/*****************************************************************************
 *
 * Class: FlFRuleBase --- Rule base and Fuzzy inference engine
 *
 *****************************************************************************/

#ifndef __FlFRuleBase_h
#define __FlFRuleBase_h

#include <fstream>
#include <stdlib.h>

#include <FlNamed.h>                // Base class
#include <FlFRule.h>
#include <FlArrayObject.h>
#include <FlFSetLR.h>


/*
 * The class FlFRuleBase
 */

class FlFRuleBase : public FlNamed
{
public:
//    enum { DEF_RESOLUTION = 101 };        // = 100 increments
    enum { DEF_RESOLUTION = 21 };           // = 20 increments
    enum States {START = 0, RULEBASE, VAR, VAR_BEGIN, SET, VAR_END, END};

    void add_rule   (FlFRule *rule);        // Add rule to base
    void add_rule   (FlFRule &rule);        // Add rule to base
    void add_in_var (FlFVar *rule);         // Add input var to base
    void add_in_var (FlFVar &rule);         // Add input var to base
    void add_out_var(FlFVar *rule);         // Add output to base
    void add_out_var(FlFVar &rule);         // Add output to base

    int get_n_rules() const;                // Get # of rules
    int get_n_in_vars() const;              // Get # of input vars
    int get_n_out_vars() const;             // Get # of output vars

    // Updates the fuzzy sets with the contents of the file specified
    // Returns TRUE if no errors
    Fl_bool updateFuzzySets(const char* filename);

    int resolution() const;                 // Return output fuzzy set resolution
                                            
                                            // Compute inference set
    void inference(FlFVar *var, FlFSet *set, double match, FlFSetArray &res);
                                            // Compute output set for variable
    void evaluate (FlFVar *var, FlFSetArray &res);

    void aggregate_all();                   // Aggregate all rules
    void evaluate_all();                    // Evaluate all variables
    void defuzzy_all();                     // Defuzzify all output variables

    void debug_rules(ostream &strm=cout, int lvl=0);
    
    // Private members
private:
    //        Aggregation operator
    // FIXME: Inference operator
    //        Accumulation operator
    FlArrayObject rules;                    // The rules
    FlArrayObject in_vars;                  // Input variables
    FlArrayObject out_vars;                 // Output variables
    int nsteps;                             // Resolution (n) of output fuzzy sets

    // This methods takes an FlArrayObject as its input and updates the fuzzy
    // sets using this information
    Fl_bool updateSets(FlArrayObject new_vars);


    // This method takes an ifstream as input, opens it and parses its
    // contents. It returns an FlArrayObject containing the new variables read
    // from this file
    Fl_bool parseInputFile(std::ifstream &inputFile, FlArrayObject* new_vars);

    /***** Constructors ******************************************************/
public:
    FlFRuleBase()
        : FlNamed(""),
          rules((size_t)0), in_vars((size_t)0), out_vars((size_t)0),
          nsteps(DEF_RESOLUTION) {}
    FlFRuleBase(FlStringR name)
        : FlNamed(name),
          rules((size_t)0), in_vars((size_t)0), out_vars((size_t)0),
          nsteps(DEF_RESOLUTION) {}
    
    // Print/debug output
    virtual void print(ostream &strm = cout) const;
    virtual void dump (ostream &strm = cout) const;
};

#endif /**__FlFRuleBase_h**/
