Chao Cac Ban

Fuzzy Logic (FL). An Implementation in Java

Fuzzy Logic is the work of Lotfi Zadeh and it relies on Mathematical Probability and also basses on Set Theory (ST). Here is for "the ease of vague understanding".

As I have already explained about FuzzyLogic in the Posting Adventure into Machine-Learning Programming with Fuzzy Logic I talked about my "own" implemented FuzzyEngine. Today I explain the way how FL is implemented. First of all: let's review it:

Fuzzy Logic is more real than "computer logic" where the reasoning is always unambiguous or imprecise. It isn't the "EITHER this (result) OR that (alternative)" conclusion, but a vague and approximate solution where there's NO alternative. Example:
Computer Logic (CL)

if a == b then c = a // result
else           c = b // alternative

with FuzzyLogic

if a similar b then c is a
  • FL is ambiguous and vague.
  • FL operations are relative (similar, is, etc.)
  • FL objects possess numerous states which can be vague and overlapping.
  • FL state (or data) is abiguous and imprecise.

Because FL is the synonym of Similarity, of Vagueness and of Approximateness FL data are indeterminate, imprecise and so FL variables become ambiguous. Thus Operations with FL data and FL variables are also vague, indeterminate and ambiguous. The result usually renders an "ambiguous state" which is in reality very common (e.g. cold, hot, warm, etc.). The following picture shows you the structural frame of FuzzyEngine implementation.

FuzzyEngine

ALT
Fig. 1: FuzzyEngine Structure

The FL-Engine implementation is a straight-forward matter. The foundation is the interpretative technology. The FL-Engine or FuzzyEngine (FE) consists of 6 basic components:

  • FuzzyScript: see the following example,
  • FuzzyRegister: All instantiatable JavaObjects should be registered before their methods and fields (variables) can be accessed. Fields of unregistered JavaObject are either null or zero. FuzzyVariables (FV) and FuzzyData must be registered before they can be referenced. Otherwise exception will be thrown.
  • FuzzySyntaxExecutor: is the Syntax-Parser-Checker and Executor at once. FuzzyExpression is checked for linguistic correction before it is executed. If all FuzzyExpressions are valid they are cached for the next execution.
  • FuzzyExecutor: is the second "Executor" which executes the cached FuzzyExpressions. This way greatly enhances the performance (good response time).
  • FuzzyLogicJavaInterface: is the mediator between FuzzyEngine and JavaObjects (active and passive as well). JavaMethods are invoked for execution by this component or JavaObjects are accessed and modified by FE via this FuzzyLogicJavaInterface.
  • FuzzyVariable: like all Computer language FL works with variables and data, too. FuzzyVariable or FV is an JavaObject (not a POJO, nor a Getter-Setter) which can contains a set of FuzzyData.
  • FuzzyData: FuzzyData or FD is a set of double values which represent a state of an object. If a range is represented by 3 double values it is a Pyramid (left, top, right). If a state is arranged by 4 double values (left, left-top, right-top, right) it's a Trapezoid. The reason why double is used because double represents an unlimited range of values. if FuzzyData is projected on a X-Y coordinate the X-Axis represents the range of samples (e.g. 10.0, 10.5, etc.) and the Y-Axis gives a value-range between 0.0 and 1.0 which are the FuzzyValues.

ALT
Fig.2: FuzzyData

The following JAVA APIs are necessary for the FuzzyLogic Implementation:

  • FuzzyData is a FuzzyState. It defines a set of values whic cover a range of possible state of an object. The set values are grouped in 3 (Pyramid) or 4 (Trapezoid) double values.
  • FuzzyVariable is the working object of FuzzyLogic. A FuzzyVariable can have several FuzzyStates or a set of FuzzyData.
  • FuzzyEngine is the engine which runs the FuzzyExpressions or Scripts. FE runs on its own and interchanges only with its JAVA host via Strings, doubles, JAVA-instantiated FuzzyVariables and JAVA methods of registered JAVA objects. FE is thread-unsafe (due to its independent interchanges with JAVA host).
  • FuzzyCluster is a remedy for FE in a multi-threading JAVA environment.

The JAVA-FL package is named fuzzylogic.

FuzzyLogic Language (FLL)

FL Operations must be able to operate on the vague state of FL objects so that any transition between the states could be rendered. Because there's NO distinct transition between different states the Set Theory operations (AND, OR, INVERSE, EXCLUSIVE/INCLUSIVE OR, INVERSE, etc.) can be optimally applied to FL. I don't go into details with Set-Theory operations, but hint you to see the given link above, or to Google for more if you want to do some researches on ST issues. Or THIS.

In order to render numerous states of a FL object FL Data must be a set of various ranges. Example: FL data for temperature:

  • cold is between -10° and +10°,
  • cool is between +8° and +18°,
  • fair is between +15° and +20°,
  • warm is between +18° and +26°,
  • hot is between +24° and +34°,

The data of Temperature can be extended, for example, to: very cold, absolute cold, very hot, boiling hot, etc. The state of each data range is floating between 0.0 to 1.0 (a double or a float. A -1.0 indicates the out of range) and has a form of either a pyramid or a trapezoid (see above).

The Y-Axis is the "Fuzzy Axis" and the X-Axis is the Sample-Axis. The perpendicular line that cuts the left or right line of the pyramid (or trapezoid) is the sample line. On the Sample-Axis it's the sampled value. The projection of the cutting point on Fuzzy-Axis gives the Fuzzy value. The calculation of the left and right area is called the "defuzzification". The result is then the final outcome of FL operations. Defuzzification can be computed as the Average which can be "fined-grained" or "coarse", or as the Center (or Centroid). An example of a FL operation:

if temperature is cool AND AirCon is low then room is cool

As we know, FL does not provide an alternative, hence the outcome is singular: room is cool. Nothing more. Nothing less. And the outcome (room) is also vague and ambiguous: cool between 8° and 18°. To implement such an engine we have to define a linguistic set of FuzzyLogic or let's say FuzzyLogic Language. I have implemented FLL with the following linguistic set. The syntax is relatively simple.

  • FD is enclosed by [...] and arranged by FDname and values. Example: [cold: -20d, -5d, 5d]
  • FV is enclosed by {...} and arranged by FVname and FDname. Example: {AirCon: min, low, OFF, high, max }
  • Access to JavaObject starts with JavaObjectName and Object/MethodName separated by a dot (.) for MethodName or a colon (:) for JavaObject. Example: this.print("Hello Java") or this:temp = temp (assign defuzzied value of FV temp to JavaObject temp).
  • FV is accessed directly by FE. Example: FV = 123 (set FV with the sample of value 123). FD is inaccessible, but only referenced by name. Example: if FV is FD then FVx is FDx
  • Conditional statement if ... then ... can have more than 1 FV expression. They are conjunct together by the keywords and, or. Example: if room is cold and AirCon is low then temp is cold. Expressions can be enclosed by brackets ( ). Example: if (room is cold and (AirCon is low)) then temp is cold. If brackets are used they must be in balance. An Open Bracket is always ended with a Closed bracket.
  • Built-in functions clear and reset are standalone. Example: clear FV. Function not, some and very are related to FD and are used within conditional if and replaced the is. Example: if FV some FD then FVx not FDx.
  • Comment starts with double slashes (//) and ends at the end of the line (similar to Java).

An Example of a valid FuzzyExpression.
ALT
Fig.3 FuzzyExpression

--------------------------------------------------------------------------------

          FuzzyLogic Keywords, Operatots, Syntax and Operations 

- FuzzyVariables and FuzzyData must be registered before FuzzyExpressions or
  FuzzyScript can be executed.

- The keyword 'this' refers to an executable JavaObject which is the Container
  of FuzzyEngine (i.e. where FE is instantiated). Registered and Unregistered
  can be referenced by FuzzyEngine. If Unregistered JavaObject is referenced, all
  the Object's contents (i.e. objects, primitives) are put in their initial
  states (or values) and they could be null or 0.

- Registered JavaObjects must be instantiated, before they are registered.
  Otherwise Exception will arise when they are referenced.

- Reference to JavaVariables (or fields): JavaObjectName:JavaVariableName, or
                                          this:JavaVariableName
- Reference to JavaMethods: JavaObjectName.JavaMethodName(Parm1, ...) or
                            this.JavaMethodName(Parm1, ...)
- Comment starts with 2 consecutive slash (/) and ends at the end of the line
  (like JAVA or C //-comment)

------------------Register FuzzyData and FuzzyVariable--------------------------
[FDname:left, top, right]
[FDname:left, ltop, rtop, right]
{FVname:FDname, FDname, ..., FDname}
--------------------------Buil-in Functions-------------------------------------
clear FV          // clear all FV-FuzzyData of FV
reset FV          // FV and all its FDs
--------------------------Operations--------------------------------------------
FV = val          // FV sample = val 
FV + val          // + FV sample with val
FV - val          // - FV sample from val
FV * val          // * FV sample by val
FV / val          // / FV sample by val
---------------Operation with JavaVariable--------------------------------------
FV = MyApp:temp   // set FV sample with JavaVariable temp of JavaClass MyApp
MyApp:temp = val  // set JavaVariable to val  
MyApp:temp + val  // add JavaVariable with val
MyApp:temp - val  // sub JavaVariable from val  
MyApp:temp * val  // mul JavaVariable by val  
MyApp:temp / val  // div JavaVariable by val  
--------------------------Statements--------------------------------------------
if FV is FD then FVr is FDr     // assign valuated result to FDr of FVr
if (FV is FD) then FVr is FDr
if FV1 is FD1 or FV2 is FD2 then FV3 is FD3 
if (FV1 is FD1) or (FV2 is FD2) then FV3 is FD3 
if (FV1 is FD1 or FV2 is FD_2) and FV3 is FD3 then FV4 is FD4
if ((FV1 is FD1 or FV2 is FD_2) and FV3 is FD3) then FV4 is FD4 
--------------------------Statements--------------------------------------------
if FV some FD ...             // fuzzySample**2 of FD
if FV very FD ...             // SQRT(fuzzySample) of FD
if FV not  FD ...             // (1-fuzzySample) of FD
if ... then FVr some FDr      // assign result**2 to FDr of FVr
if ... then FVr very FDr      // assign SQRT(result) to FDr of FVr
if ... then FVr not  FDr      // assign 1-result to FDr of FVr
-----------------------Operators and Syntax-------------------------------------
// starts a comment and ends at end of the Line
+ - * / = : . 

---------------------------Keywords---------------------------------------------
this
reset
clear
some
very
not
and
or
if
then
is
--------------------------------------------------------------------------------

and here is an example of a FuzzyScript

// register FuzzyData for Temperature
[cold: -20d, -5d, 5d]
[cool: 2d, 10d, 20d]
[fair: 19d, 20d, 22d]
[warm: 21d, 23d, 25d]
[hot:  24d, 30d, 50d]
// register FuzzyData for AirConditioner
[min: -10d, -6d, -3d]
[low: -4d, -2d, 0]
[OFF: -0.5d, 0, 0.5d]
[high: 0d, 2d, 4d]
[max:  3d, 6d, 10d]
// register FuzzyVariables
{AirCon: min, low, OFF, high, max }
{room: cold, cool, fair, warm, hot }
{temp: cold, cool, fair, warm, hot }
// call built-in clear to clean up FV AirCon
clear AirCon
// set Samples from JavaObject temp
room = this:temp
// FL reasoning for AirConditioner
if room is cold then AirCon is max
if room is cool then AirCon is high
if room is fair then AirCon is OFF
if room is warm then AirCon is low
if room is hot  then AirCon is min
// set AirCon with defuzzied FV
this.print("Time to run")
this.print("Room:", room)
AirCon = this.adjust(AirCon)
// FL reasoning for temp with 'and' for 2 FVs
if room is cold and AirCon is min then temp is cold
if room is cool and AirCon is min then temp is cold
if room is fair and AirCon is min then temp is cold
if room is warm and AirCon is min then temp is cool
if room is hot  and AirCon is min then temp is fair

if room is cold and AirCon is low then temp is cold
if room is cool and AirCon is low then temp is cold
if room is fair and AirCon is low then temp is cool
if room is warm and AirCon is low then temp is fair
if room is hot  and AirCon is low then temp is warm

if room is cold and AirCon is OFF then temp is cold
if room is cool and AirCon is OFF then temp is cool
if room is fair and AirCon is OFF then temp is fair
if room is warm and AirCon is OFF then temp is warm
if room is hot  and AirCon is OFF then temp is hot

if room is cold and AirCon is high then temp is cool
if room is cool and AirCon is high then temp is fair
if room is fair and AirCon is high then temp is warm
if room is warm and AirCon is high then temp is hot
if room is hot  and AirCon is high then temp is hot

if room is cold and AirCon is max then temp is fair
if room is cool and AirCon is max then temp is warm
if room is fair and AirCon is max then temp is hot
if room is warm and AirCon is max then temp is hot
if room is hot  and AirCon is max then temp is hot
// end of FuzzyExpression
// call JavaMethod print() and print(String)
this.print("End of Fuzzy. RoomTemp:", temp)
this.print()
// assign the defuzzified value of temp to JavaObject temp
this:temp = temp

FuzzyLogic Application and Integration over Java

The question is "Where is FL good for?". The answer is clear and simple: to suit the real human requirements which are usually unclear, vague and ambiguous. AI is man-made Intelligence -a reflection of human intelligence upon a machine. The imagination of "Room is cool" is very ambiguous. For an Eskimo 21.8° Celsius (or 71.24° Farenheit) is quite warm, or probably "hot". For a Saigoner it's a freshing boon. Who's right? The Eskimo or the Saigoner? From this stand point FL is the ideal way to implement AI. FL allows human to see things as they are: relative, ambiguous, approximate and somehow very common.

The Vagueness and Relativeness make PYTHON to the champ of AI-Programming Language (AIPL). Its simplicity (e.g. typeless objects) is the most spoken reason why "man" selects PYTHON. But who's "man". The "man" is the one who comes from other field than IT field. He has to work with computer and has no desire to deepen his IT knowledge -just like a clerk in every office. But if you've studied Computer Science then why you ride on the PYTHON wagon and limit yourself like a "man" who comes from other field? I like PYTHON, too. PYTHON is superb for a small AI-Task. However, for a big complex AI-Machine (e.g. DataMining) PYTHON is swamped, highly overchallenged.

As we've learned that FuzzyLogic is strikingly suited to human sense which is never "precise" or "crisp", but always vague and ambiguous. In conjunction with any higher OOPL AI development would be easier and more approximate to Human Intelligence. I have implemented FL in JAVA and, of course, the FL JAVA-package must work and runs in sync with JAVA environment, too.

ALT

The Intercommunication between FuzzyEngine and JavaObjects is done in two ways:

  • JavaObjects are registered, or
  • JavaObjects are unregistered

Active JavaObject is an instantiated object. And it must be registered so that its actual state is always available for FuzzyEngine. If FE is instantiated with an active JavaObject this JavaObject is the main JavaObject and can be referenced in FuzzyScript with its ClassName or "this". Example:

room = this:temp             // FV sample is set with the double temp of running JavaObject
AirCon = this.adjust(AirCon) // AirCon Sample is set with the returned of method "adjust"
                             // with the parm from defuzzied FV AirCon.
this.print("Time to run")    // call the method print with the passing parmameter
                             // "Time to run"

Passive JavaObject is an uninstantiated JavaObject and can be only referenced by its ClassName. Passive JavaObjects need NOT to be registered. However, if an object of a passive JO is referenced (e.g. a primitive double) the content of the referenced is undefined. It could be null or zero. Example:

room = AHouse:temp             // FV sample is set with AHouse's double temp
AirCon = AHouse.adjust(AirCon) // AirCon Sample is set with the returned of AHouse's method
                               // "adjust" with the parm from defuzzied FV AirCon.
AHouse.print("Time to run")    // call AHouse's method print with the passing parameter 
                               // "Time to run"

FE works only with one main Active JavaObject and this "main" can be removed and replaced by another active JavaObject. Example (JavaContainer):

public class JFXhouse extends Application {
   ....
   FuzzyEngine fe = new FuzzyEngine(this, "JFXhouse"); // instantiated with Container
   ...
   fe.removeObject("JFXhouse");                        // drop JFXhouse as Container
   AHouse ahouse = new AHouse();                       // create a new JavaObject
   fe.setContainer(ahouse, "AHouse", true);            // set new main and overwrite
   ...

The given example JFXhouse.java is written in JavaFX and it gives you 2 possibilities:

  • Fuzzy: controlled and managed the Room's temperature (optimal between 19°..22°) by FuzzyScript
  • Manual: you control and manage the Room's temperature using the AirCon Slider.

And you'll be aware how difficult it is, to be approximate to the optimal temperature between 19° and 22° and how "fast" FuzzyEngine moves to the best temperature.

import fuzzylogic.FuzzyEngine;
// Joe Nartca
public class JFXhouse extends Application {
  // JFX start
  public void start(Stage stage) {
    stage.setTitle("JFXhouse controlled by FuzzyLogic");
    ran = new java.util.Random();
    //
    step = 0;
    outside = (double)ran.nextInt(33);
    if (ran.nextInt(2) > 0) outside = -outside;
    // preset Room Temperature between -10 to 32 Celsius
    temp = outside < -10d? -10d:(outside > 32)? 32:outside;
    // FuzzyLogic..............................
    eng = new FuzzyEngine(this, "JFXhouse");
    try {
      // registered java Variable step of this class
      eng.regJavaVariable("this:temp", temp);
      eng.regJavaVariable("this:step", step);
    } catch (Exception ex) {
      ex.printStackTrace();
      stop();
    }
    //
    Canvas canvas = new Canvas(500, 440);
    gc = canvas.getGraphicsContext2D();
    //
    Slider slider = new Slider();
    slider.setMin(-10d);
    slider.setMax(10d);
    slider.setValue(step);
    slider.setDisable(true);
    slider.setShowTickLabels(true);
    slider.setShowTickMarks(true);        
    slider.setBlockIncrement(0.5d);
    slider.valueProperty().addListener((obs, oldVal, newVal)-> {
      step = (Double) newVal;// scale: (32+10)/20 = 2.1
      temp += step * 2.1; // scaling temp
      if (temp < -10d) temp = -10d; // min temp
      else if (temp > 32d) temp = 32d; // max temp
      paint(String.format("Outside: %2.2f Celsius. AirCon: %2.2f. Room's Temp %2.2f Celsius",
                          outside, newVal, temp));
    });  
    GO = new Button("FUZZY");
    GO.setPrefWidth(80);
    GO.setOnAction(e -> {
      try {
        GO.setDisable(true);
        MAN.setDisable(true);
        slider.setDisable(true);
        paint(String.format("Current Room's Temperaature %2.2f",temp));
        // the values between 20d and 22d are the so-called LEARNED values
        while (temp < 20d || temp > 21d) {
          eng.execute("thishouse.txt");
        }
      } catch (Exception ex) {
        ex.printStackTrace();
        stop();
      }
      slider.setDisable(true);
      MAN.setDisable(false);
      GO.setDisable(false);
    });

    MAN = new Button("MANUAL");
    MAN.setPrefWidth(80);
    MAN.setOnAction(e -> {
      GO.setDisable(true);
      MAN.setDisable(true);    
      slider.setDisable(false);
    });

    Button NEW = new Button("RESET");
    NEW.setPrefWidth(80);
    NEW.setOnAction(e -> {
      GO.setDisable(false);
      MAN.setDisable(false);    
      slider.setDisable(true);
      double d = (double)ran.nextInt(33);
      outside = (ran.nextInt(10) > 5? d:-d);
      // preset Room Temperature between -10 to 32 Celsius
      temp = outside < -10d? -10d:(outside > 32)? 32:outside;
      paint(String.format("Reset. New outside temperature %2.2f.", outside));
    });

    HBox hbb = new HBox();    
    hbb.setPadding(new Insets(10));
    hbb.setSpacing(10);
    hbb.setAlignment(Pos.CENTER);
    hbb.getChildren().addAll(GO, MAN, NEW);
    //
    Label lab = new Label("AirController");
    VBox vbs = new VBox();
    vbs.setPadding(new Insets(5, 5, 5, 5));
    vbs.getChildren().addAll(lab, slider);
    //
    VBox vbox = new VBox();
    // Insets(top, right, bottom, left)
    vbox.setPadding(new Insets(5, 0, 5, 9)); // aliceblue
    vbox.setBackground(new Background(new BackgroundFill(Color.web("#f0f8ff"),
                                                          CornerRadii.EMPTY,
                                                          Insets.EMPTY )));
    vbox.getChildren().addAll(hbb, canvas, vbs);
    //
    Scene scene = new Scene(vbox, 500, 590);
    stage.setResizable(false);
    stage.setScene(scene);
    stage.setX(30); 
    stage.setY(30);  
    stage.show();
    // set Outside temperature
    paint("Outside Temperature "+String.format("%2.2f Celsius.", outside));
  }
  public void stop() {
    Platform.exit();
    System.exit(0);
  }
  //
  private void paint(String msg) {
    if (gc == null) return;
    if (temp < 5) {
      gc.setFill(Color.MEDIUMBLUE);
      gc.fillRect(0, 0, 480, 440);
      gc.setStroke(Color.WHITE);
    } else if (temp <  19) {
      gc.setFill(Color.PALETURQUOISE);
      gc.fillRect(0, 0, 480, 440);
      gc.setStroke(Color.MEDIUMBLUE);
    } else if (temp <  22) {
      gc.setFill(Color.FLORALWHITE);
      gc.fillRect(0, 0, 480, 440);
      gc.setStroke(Color.DARKSEAGREEN);
    } else if (temp <= 24) {
      gc.setFill(Color.PINK);
      gc.fillRect(0, 0, 480, 440);
      gc.setStroke(Color.DARKRED);
    } else {
      gc.setFill(Color.DARKRED);
      gc.fillRect(0, 0, 480, 440);
      gc.setStroke(Color.YELLOW);
    }
    gc.strokeText(msg, 50, 200);
  }
  //--------------------- invoke by FuzzyScript
  private void print( ) {
    paint(String.format("Outside %2.2f Celsius, Room %2.2f Celsius, AirCon %2.2f",
                         outside, temp, step));
  }
  private void print(String msg) {
    paint(msg+String.format(" (Room:%2.2f)", temp));
  }
  private void print(String msg, double d) {
    temp = d; // set the new temperature
    paint(msg+String.format(" %2.2f", d));
  }
  private double adjust(double d) {
    double x = temp < 5d? 1d:temp < 20d?0.5d:temp < 25d? -0.5:-1d;
    step = d + x;
    paint(String.format("Defuzzy step:%2.2f -> new step:%2.2f by temp:%2.2f", d, step, temp));
    return step;
  }
  //
  private Button GO, MAN;
  private FuzzyEngine eng;
  private GraphicsContext gc;
  private java.util.Random ran;
  private double temp, step, outside;
}

The FuzzyScript

// Temperature states
[cold: -20d, -5d, 5d]
[cool: 2d, 10d, 20d]
[fair: 19d, 20d, 22d]
[warm: 21d, 23d, 25d]
[hot:  24d, 30d, 50d]
// AirCon regulator states
[min: -10d, -6d, -3d]
[low: -4d, -2d, 0]
[OFF: -0.5d, 0, 0.5d]
[high: 0d, 2d, 4d]
[max:  3d, 6d, 10d]
// FuzzyVariables
{AirCon: min, low, OFF, high, max }
{room: cold, cool, fair, warm, hot }
{temp: cold, cool, fair, warm, hot }
// set Samples to Java Global Variables
clear AirCon
room = this:temp
if room is cold then AirCon is max
if room is cool then AirCon is high
if room is fair then AirCon is OFF
if room is warm then AirCon is low
if room is hot  then AirCon is min
// set AirCon with defuzzied FV
this.print("Time to run")
this.print("Room:", room)
AirCon = this.adjust(AirCon)
// FuzzyExpressions
if room is cold and AirCon is min then temp is cold
if room is cool and AirCon is min then temp is cold
if room is fair and AirCon is min then temp is cold
if room is warm and AirCon is min then temp is cool
if room is hot  and AirCon is min then temp is fair

if room is cold and AirCon is low then temp is cold
if room is cool and AirCon is low then temp is cold
if room is fair and AirCon is low then temp is cool
if room is warm and AirCon is low then temp is fair
if room is hot  and AirCon is low then temp is warm

if room is cold and AirCon is OFF then temp is cold
if room is cool and AirCon is OFF then temp is cool
if room is fair and AirCon is OFF then temp is fair
if room is warm and AirCon is OFF then temp is warm
if room is hot  and AirCon is OFF then temp is hot

if room is cold and AirCon is high then temp is cool
if room is cool and AirCon is high then temp is fair
if room is fair and AirCon is high then temp is warm
if room is warm and AirCon is high then temp is hot
if room is hot  and AirCon is high then temp is hot

if room is cold and AirCon is max then temp is fair
if room is cool and AirCon is max then temp is warm
if room is fair and AirCon is max then temp is hot
if room is warm and AirCon is max then temp is hot
if room is hot  and AirCon is max then temp is hot
// end of FuzzyExpression
this.print("End of Fuzzy. RoomTemp:", temp)
this.print()
this:temp = temp

The download package from CDJ includes:

  • Directory Example with different ways how to create a FL-Java App
  • JavaDoc-Style for the Fuzzy APIs
  • fuzzylogic.jar

If you want the sources please Inbox me (@Congdongjava.com) and I'll inform you about the conditions for the FL-package.