Go to the first, previous, next, last section, table of contents.


Fuzzy Prolog

Author(s): Claudio Vaucheret, Sergio Guadarrama.

This package impements an extension of prolog to deal with uncertainty. We implement a fuzzy prolog that models interval-valued Fuzzy logic. This approach is more general than others Fuzzy Prolog in two aspects:

  1. Truth value will be a sub-interval on [0,1]. In fact, it could be a finite union of sub-intervals as we will see below. Having a unique truth value is a particular case modeled with a unitary interval.
  2. Truth value will be propagated through the rules by means of a set of aggregation operators. The definition of an aggregation operator is a generalization that subsumes conjunctive operators (triangular norms as min, prod, etc), disjunctive operators (triangular co-norms as max, sum, etc), average operators (averages as arithmetic average, cuasi-linear average, etc) and hybrid operators (combinations of previous operators).

We add uncertainty using CLP(R) instead of implementing a new fuzzy resolution as other fuzzy prologs. In this way, we use the original inference mechanism of Prolog, and we use the constraints and its operations provided by CLP(R) to handle the concept of partial truth. We represent intervals as constrains over real numbers and aggregation operators as operations with constraints.

Each fuzzy predicate has an additional argument which represents its truth value. We use ":~" instead of ":-" to distinguish fuzzy clauses from prolog clauses. We have implemented the following aggregation operators:

  1. min minimum T-norm.
  2. prod product T-norm.
  3. luka Lukasiewicz T-norm.
  4. max maximum T-conomr.
  5. dprod product T-conomr.
  6. dluka Lukasiewicz T-conorm.

An example of code can be:

:- module(young2,_,[fuzzy]).

young_couple(X,Y,Mu) :~ min
        age(X,X1),
        age(Y,Y1),
        young(X1,MuX),
        young(Y1,MuY).

age(john,37).
age(rose,39).

young :# fuzzy_predicate([(0,1),(35,1),(45,0),(120,0)]).

?- young_couple(john,rose,M).

.=.(M,0.6) ? 

yes
?- 

Fuzzy predicates with piecewise linear continous membership functions like young in the example above is translated to aritmetic constraints, the translation is the following:

young(X,1):- X .>=. 0, X .<. 35.
young(X,M):- X .>=. 35, X .<. 45, 10*M .=. 45-X.
young(X,0):- X .>=. 45, X .=<. 120. 

It is possible to fuzzify crisp predicates. For example to fuzzify p/2 it is only necessary to write:

p_f :# fuzzy p/2

and the program is expanded with a new fuzzy predicate p_f/3 (the last argument is the truth value) with truth value equal to 0 if p/2 fail and 1 otherwise.

We provide too the possibility of having the predicate that is the fuzzy negation of a fuzzy predicate. For this predicate p_f/3 we will define a new fuzzy predicate called for example notp_f/3 with the following line:

notp_f :# fnot  p_f/3

that is expanded at compilation time as:

notp_f(X,Y,M) :-
        p_f(X,Y,Mp),
        M .=. 1 - Mp.

Another example is:

:- module(dicesum5,_,[fuzzy]).

% this example tries to measure which is the possibility
% that a couple of values, obtained throwing two loaded dice, sum 5. Let
% us suppose we only know that one die is loaded to obtain a small value
% and the other is loaded to obtain a large value. 
%
% the query is  ? sum(5,M)
%

small :# fuzzy_predicate([(1,1),(2,1),(3,0.7),(4,0.3),(5,0),(6,0)]).
large :# fuzzy_predicate([(1,0),(2,0),(3,0.3),(4,0.7),(5,1),(6,1)]).

die1(X,M) :~
        small(X,M).

die2(X,M) :~
        large(X,M).

two_dice(X,Y,M):~ prod
        die1(X,M1),
        die2(Y,M2).

sum(2,M) :~  
        two_dice(1,1,M1).

sum(5,M) :~ dprod
        two_dice(4,1,M1),
        two_dice(1,4,M2),
        two_dice(3,2,M3),
        two_dice(2,3,M4).

Usage and interface (fuzzy)


Go to the first, previous, next, last section, table of contents.