Fuzzy machine learning API
Author: Dmitry Kazakov
Description: Machine learning framework based on fuzzy intuitionistic sets, possibility theory. Object oriented, written in Ada
Keywords: fuzzy, machine learning, learning with a teacher, graph, fuzzy graph, graph-scheme, artificial intelligence, possibility, necessity, intuitionistic set, feature, fuzzy feature, GNU, GPL, free, ODBC, public domain, OO, object-oriented, Ada, Ada 95

FUZZY MACHINE LEARNING FRAMEWORK |  | by Dmitry A. Kazakov (mailbox@dmitry-kazakov.de) |  | Application Programming Interface
with fuzzy graph-schemes | version 1.12

This library is free software; you can redistribute it and/or modify it under the terms of the GNU 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this library; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

As a special exception, if other files instantiate generics from this unit, or you link this unit with other files to produce an executable, this unit does not by itself cause the resulting executable to be covered by the GNU General Public License. This exception does not however invalidate any other reasons why the executable file might be covered by the GNU Public License.

Fuzzy machine learning framework downloading page

The approach to fuzzy machine learning used here is based on the possibility theory. Events, features and classes are considered as being fuzzy. Fuzzy decision graphs are used as the knowledge carrier. The software was designed in an object-oriented manner. All objects it works with are extensible and can be created and destroyed dynamically. The resources used by objects are reclaimed automatically as they become unused. The software was written in Ada 2005, though except for some exceptions it is in compliance with Ada 95. The Ada language offers the best available level of safety and maintainability not compromising the efficiency. The current version was tested with the GNAT Ada compiler. It includes distributions of fuzzy sets, string edit, tables and interval arithmetic packages.

The key features of the software:

- Based on intuitionistic fuzzy sets and the possibility theory;
- Features are fuzzy;
- Fuzzy classes, which may intersect and can be treated as features;
- Numeric, enumeration features and ones based on linguistic variables;
- Derived and evaluated features;
- Classifiers as features for building hierarchical systems;
- User-defined features;
- An automatic classification refinement in case of dependent features;
- Incremental learning;
- Object-oriented software design;
- Features, training sets and classifiers are extensible objects;
- Automatic garbage collection;
- Generic data base support (through ODBC);
- Text I/O and HTML routines for features, training sets and classifiers;
- GTK+ widgets for features, training sets and classifiers;
- Examples of use.

See also the changes log.

## 1. A necessary introduction

The concept of learning (training) and classification is based on the notion of feature. A feature is something that can be measured and then used for classification. I assume that the process of measurement cannot be separated from what is being measured. In other words the measured thing cannot be sensed directly. This is how uncertainty usually comes into the play. Whether this uncertainty is a part of the "real world" or a side effect of the measurement process is only of philosophical interest. It is helpful to observe two different kinds of uncertainty: randomness and fuzziness. A statistical or probabilistic approach to pattern recognition treats whole uncertainty as randomness. With this approach the features are random variables. On the contrary a fuzzy approach treats uncertainty as fuzziness, so the fuzzy features become mappings resulting in fuzzy subsets of the feature domain set.

It is important to note that neither probabilistic nor fuzzy approach may supersede another because neither randomness nor fuzziness can be adequately described by another. So it would be wrong to think of the fuzzy pattern recognition theory as a generalization of the statistical pattern recognition. Neither it is an alternative theory, because they have different, though intersecting, application domains. There can exit intermixed variants of both. It is also important to observe that the features related to physical processes would most likely be random variables. For instance, the quantum mechanics is based solely on the probability theory.

One could ask, why not to always use the statistical approach for physical processes, if the nature seem to behave in accordance with the probability theory? The answer is, yes, do it when it works. Unfortunately, in many cases it does not. And even if the "real word" is not the source of fuzziness, the way we perceive it definitely is. So the theories we invent to describe stochastic systems are fuzzy where perception gets involved. Often the fuzzy component in our knowledge of a physical process prevails any uncertainty the randomness of the process may contribute. I.e. we know so little that it makes no difference.

The bottom line is, only if deterministic methods do not work, if statistical models are inadequate, then one should choose fuzzy methods.

In the future discussion I will use the formulation of the problem of fuzzy learning with a teacher as described in On Intuitionistic Fuzzy Machine Learning.

### 1.1. Fuzzy graph-schemes

Fuzzy_graph of Berge G is defined as a fuzzy binary relation G:E×E→[0,1], i.e. a fuzzy subset of E2, where countable E is the set of graph nodes. a G b = G(a,b)∈[0,1] tells whether there is an arc in G leading from a to b. We will consider fuzzy graphs having a finite number of nodes and no cycles. There could be graphs of possibilities and necessities depending on the meaning addressed to fuzzy a G b:

Graph of | a G b = | Meaning
Possibilities | Pa→b | The possibility that there is an arc a→b
Necessities | Na→b | The necessity that there is an arc a→b

Composition GºG=G2 of fuzzy binary relations is defined as ∀a, b∈E:

Graph of | a G2 b = | Meaning
Possibilities |
Sup v∈E | Pa→v & Pv→b
| The possibility that there is a path a→b over some third node
Necessities |
Inf v∈E | Na→v ∨ Nv→b
| The necessity of that

It can be shown that for the closure G*=GºGº... and for any two nodes a and t, there is always a path a→ b→ c→ .. → s→ t for which:

Graph of | a G* b = | Meaning
Possibilities | Pa→b & Pb→c & ... & Ps→t | There is a path a→t which possibility equals to a G* t
Necessities | Na→b ∨ Nb→c ∨ ... ∨ Ns→t | There is a path a→t which necessity equals to a G* t

Informally, along a path the possibilities are combined using min, the necessities are combined using max. In a node the possibilities from different paths are combined using max, while the necessities are combined using min. Graphs of necessities are complimentary to the graphs of possibilities. So one can consider only the graphs of possibilities.

Fuzzy graph-scheme is a function mapping fuzzy events to fuzzy graphs. A graph scheme consists of four graph-valued functions (GP, GN, GP, GN). The first pair (GP, GN) is obtained from learning on has-in and has-out images. Another (GP, GN) is built from has-not and has-not-out. In each pair the first component yields a graph of possibilities. The second does one of necessities. In each pair the result graphs share the set of nodes. The weights of the arcs are functions of the classified event q. It is a G b = a G(q) b. Each node a in a result graph is associated with some feature xi. It is said that the node a tests the feature xi. Nodes testing the class-feature are called terminal nodes or leaves. All result nodes are always same, only the weights vary.

- Each pair, (GP, GN) and (GP, GN), yields one root node.
- Each arc leading out of a non-terminal a testing xi into some other node b has a weight xi(a→b). This weight is a fuzzy subset of the domain of the feature xi. For the pair (GP, GN) the weight is denoted as xi(a→b) to highlight the fact that its graphs are working with the complementary images xi(·).

> > a | xi(a→b) |  | b
> > xi
> > |  | > |
> > xj

- Each result leaf node t has cj(t), a classification (cj is a class-feature) associated with it. Note that the graphs of the possibilities and necessities in each par share the nodes. So actually the possibility component of the leaf node classification belongs to the graph of possibilities while the necessity component belongs to the graph of necessities.

Now let q[xi]↑ and q[xi]↑ be images of the tested feature, then the resulting graphs will have:

Graph of | a G(q) b = | Meaning
Possibilities (GP) | Pxi(a→b)|q[xi]↑ | An upper estimation of the possibility that we should follow the arc if q
Possibilities (GP) | Pxi(a→b)|q[xi]↑ | An upper estimation of the possibility that we should follow the arc if q
Necessities (GN) | Nxi(a→b)|q[xi]↑ | A lower estimation of the necessity that we should follow the arc if q
Necessities (GN) | Nxi(a→b)|q[xi]↑ | A lower estimation of the necessity that we should follow the arc if q

A graph-scheme may act as a classifier for a fuzzy event q. Let T is the set of terminal nodes and r is the root node in a pair. Then any pair will give a classification of q:

Graph of possibilities | Graph of necessities
Pcj|q ≤ | ∪ t∈T | r G*(q) t ∩ cj(t)↑
Ncj|q ≥ | ∩ t∈T | r G*(q) t ∪ cj(t)↓

The classifications given by both pairs are combined using intersection, which is min for possibilities and max for necessities.

It can be shown that any training set can be represented by a graph-scheme and any graph-scheme has a corresponding training set. In other words graph-schemes can be used as a knowledge carrier.

## 2. Public interfaces

The packages of the software are subdivided into ones providing public services and ones used privately. Use of the software requires knowledge of the public part only. The private part have to be considered when an extension of the software is intended. When possible, the privately used packages are declared private. Unfortunately it is not always the case.

### 2.1. Objects and handles

All important objects the software deals with, are designed for an automatic garbage collection. They are created dynamically and never explicitly destroyed. An application program usually have no direct access to such objects. Instead of that it works through object's handles. As long at least one handle to an object exists, the object will not be destroyed. Thus one does not need to care about memory allocation problems. See components for further information. The following are the basic objects the software works with:

- Classifier_Handle refers to a fuzzy classifier object;
- Defuzzifier_Handle refers to an object specifying a defuzzification method;
- Feature_Handle refers to a fuzzy feature object;
- Lecture_Handle refers to a fuzzy training set. Training sets are used in both training and classification;
- Node_Handle refers to a fuzzy graph node and also to the graph rooted in this node. Fuzzy graphs are components of classifiers;
- Indicator_Handle refers to a progress indication object;
- Storage_Handle refers to a persistent storage interface object. Persistent storage is used to store other objects between program runs. In can be any ODBC-conform database.

The objects can be stored into a persistent storage, usually a data base, and then restored from there.

### 2.2. Containers

There is a set of generic packages providing different sorts of containers. The container types used (such as sets of handles) are defined through instantiation of these packages. There might be no need to use these packages directly, however, for a better understanding, how the specialized container types work, see components.

### 2.3. Fuzzy features

Fuzzy features are implemented as objects. A fuzzy feature is something that can be measured and then used for classification and learning. The set of classes is also a feature called class-feature. The domain set of a feature is the set of values it can take. A feature value consists of fuzzy characteristics, which are fuzzy subsets of the feature domain. The privately used child package Fuzzy.Feature defines the abstract type Feature_Object serving as a base for all feature objects. As it was said objects are accessible only through handles to them. Therefore all public operations on features are defined in terms of feature handles.

#### 2.3.1. Handles to features

The child package Fuzzy.Feature.Handle defines the type Feature_Handle used for general access to a feature:

> `type Feature_Handle is tagged private;`

The following operations are defined on a feature handle:

> `procedure Create_Constraint
> ( Feature : Feature_Handle;
> Context : in out Context_Object'Class;
> Allowed : Boolean := True
> );`

This procedure is used to put a new constraint on the values of Feature in some context specified by the parameter Context. The parameter Allowed specifies the initial state of the constraint. If true, then the constraint allows all values allowed at the moment. Otherwise it disallows all feature values. Once created a constraint can be modified using Set_Constraint and Set_Range procedures. The type Context_Object is defined in the parent package Fuzzy.Feature. Constraint_Error is propagated if the handle Feature is invalid.

> `procedure Delete (Feature : in out Feature_Handle);`

This procedure requests deletion of a Feature. Feature becomes an invalid handle. The feature object itself is deleted if possible. Nothing happens if Feature is not a valid handle. Note that when Feature is used in any training set then its deletion will remove it from all that sets.

> `function Get_Cardinality (Feature : Feature_Handle)
> return Positive;`

The cardinality of a feature is one its domain set. It is the number of elements in the set, or else the number of different elements there. A feature value is a set of images, fuzzy sets built over 1..Cardinality. Constraint_Error is propagated if the handle Feature is invalid.

> `function Get_Class (Feature : Feature_Handle)
> return String;`

The feature class is known to the procedures dealing with the external persistent storage. When a feature is archived, the way a feature is converted to its canonical form in the persistent storage depends on the class. This function returns the feature class. It raises Constraint_Error if Feature is invalid.

> `function Get_Constraint
> ( Feature : Feature_Handle;
> Context : access Context_Object'Class
> ) return Domain_Subset;`

This function returns the current constraint on the feature values in the context specified by the parameter Context. That is a Boolean array (1..Cardinality) in which for a feature domain value index true is set when the domain value is allowed by the constraint. The types Context_Object and Domain_Subset are defined in the parent package Fuzzy.Feature. Constraint_Error is propagated if the handle Feature is invalid.

> `function Get_ID (Feature : Feature_Handle)
> return Feature_ID;`

Each feature has an unique identification number associated with it. This function returns the identification number of Feature. The result type is defined in the package Fuzzy.Feature. Feature identifiers are comparable. Constraint_Error is propagated if the handle Feature is invalid.

> `function Get_Name (Feature : Feature_Handle)
> return String;`

This function returns the name of Feature. The feature name is usually a description of what the feature is. Note that it is not the name of the feature in a persistent storage. Constraint_Error is propagated if the handle Feature is invalid.

> `procedure Invalidate (Feature : in out Feature_Handle);`

This procedure detaches handle Feature from the feature object (if any) it points to. The result handle cannot be used to access any object. The referenced object is destroyed if it was the last handle.

> `function Is_Computed
> ( Feature : Feature_Handle;
> Source : Feature_Handle
> ) return Boolean;`

This function can be used to test whether the values of Feature are computed from the values of Source. For any feature x it is assumed that Is_Computed (x, x) is true. Is_Computed is transitive so that if both Is_Computed (x, y) and Is_Computed (y, z) is true, then Is_Computed (x, z) is true as well. Constraint_Error is propagated if either Feature or Source is invalid.

> `function Is_Valid (Feature : Feature_Handle) return Boolean;`

This function checks whether the handle Feature points to an object.

> `function Ptr (Feature : Feature_Handle) return Feature_Object_Ptr;`

This function is used to get a pointer to the feature object a handle points to. Constraint_Error is propagated if the handle is invalid. The pointer of to the object shall be used no longer the handle it was get from exists.

> `function Ref (Feature : Feature_Object_Ptr) return Feature_Handle;`

This function is used to get a handle from a pointer to a feature object.

> `procedure Ref
> ( Handle : in out Feature_Handle;
> Feature : Feature_Object_Ptr
> );`

This procedure assigns a new feature object to handle.

> `procedure Set_Constraint
> ( Feature : Feature_Handle;
> Context : in out Context_Object'Class;
> Value : Positive;
> Allowed : Boolean := False
> );`

The effect of this procedure is changing the feature constraint so that it will or not allow Value. If no constraint was imposed on the feature it is created using Create_Constraint with the parameter Allowed set to not Allowed. The parameter Value is the number of the domain set element to allow or not to. When Allowed is true, the effect of the operation depends on the stack of currently active constraints. It will not allow a value disabled by any constraint before. The type Context_Object is defined in the parent package Fuzzy.Feature. Constraint_Error is propagated when Value is an illegal domain value or Feature is not a valid handle.

> `procedure Set_Constraint_Range
> ( Feature : Feature_Handle;
> Context : in out Context_Object'Class;
> From : Positive;
> To : Natural;
> Allowed : Boolean := False
> );`

This procedure is equivalent to Set_Constraint applied to a range From..To. Nothing happens when the range is empty. Constraint_Error is propagated when the range contains an illegal domain value or Feature is not a valid handle.

> `procedure Set_Name
> ( Feature : in out Feature_Handle;
> Name : String
> );`

This procedure changes the name of Feature.

> `procedure Set_Range
> ( Feature : Feature_Handle;
> Context : in out Context_Object'Class;
> From : Positive;
> To : Positive
> );`

The effect of this procedure is changing the feature constraint so that all values outside From..To will be saturated to the closest boundary. If no constraint was imposed on the feature it is first created using Create_Constraint with the parameter Allowed set to true. Constraint_Error is propagated when From..To is an illegal domain values range or Feature is not a valid handle.

> `function To_Deposit_Handle (Feature : Feature_Handle)
> return Deposit_Handles.Handle;`

This function provides handle conversion from Feature_Handle to a general persistent object handle. Constraint_Error is propagated when Feature is not a valid handle.

> `function To_Feature_Handle
> ( Feature : Deposit_Handles.Handle
> ) return Feature_Handle;`

This function provides a backward handle conversion from a general persistent object handle to Feature_Handle. Constraint_Error is propagated when Feature is not a valid handle or does not refer a feature object.

> `function "<" (Left, Right : Feature_Handle) return Boolean;
> function "<="(Left, Right : Feature_Handle) return Boolean;
> function ">="(Left, Right : Feature_Handle) return Boolean;
> function ">" (Left, Right : Feature_Handle) return Boolean;
> function "=" (Left, Right : Feature_Handle) return Boolean;`

Valid feature handles are comparable. If one of arguments is invalid Constraint_Error is propagated for all functions except "=". For equality (and thus inequality) it is legal to compare with an invalid handle. The result of such comparison is true if and only if both handles are invalid. One of parameters in equality is allowed to be a pointer to an object.

The package defines the constant handle No_Feature which refers no feature object. It also defines the following data types:

> `type Feature_Array is array (Integer range <>) of Feature_Handle;
> type Feature_Array_Ptr is access all Feature_Array;`

#### 2.3.2. Feature containers

The following packages provide containers for feature handles. Being in a container the object is will not be destroyed until it is there.

Sets | The package Fuzzy.Feature.Handle.Container is a set of handles. It has the same interface as the package Object.Handle.Generic_Set. It defines the type Set which represents a set of feature handles.
Bounded arrays | The package Fuzzy.Feature.Handle.Bounded_Arrays provides bounded arrays of features. Basically it is an instantiation of the package Generic_Bounded_Array. It has exactly the same interface. Though for implementation reasons it is rather a proxy than being an immediate instantiation. It additionally provides the following conversion subprograms: `function To_Bounded_Array (Container : Feature_Array) return Bounded_Array;` `function To_Feature_Array (Container : Bounded_Array) return Feature_Array;`
Tables | The package Fuzzy.Feature.Handle.Tables is an instantiation of the package Tables with Feature_Handle. A feature table is map from text strings to Feature_Handle.
Unbounded_Arrays | The package Fuzzy.Feature.Handle.Unbounded_Arrays provides bounded arrays of features. Basically it is an instantiation of the package Generic_Unbounded_Array. It has exactly the same interface. Though for implementation reasons it is rather a proxy than being an immediate instantiation. It additionally provides the following conversion subprograms: `function To_Unbounded_Array (Container : Feature_Array) return Unbounded_Array;` `function To_Feature_Array (Container : Unbounded_Array) return Feature_Array;`

#### 2.3.3. Feature factory

The package Fuzzy.Feature.Handle.Factory provides a factory of fuzzy features. Its functions dynamically create of fuzzy feature objects based on different sorts of domain sets:

> independent | discrete | integer
> nominal
> continuous | real | interval-valued
> isosceles trapezoid-valued
> linguistic variables
> output (with a defuzzifier)
> deduced | binary | mutually dependent
> mutually independent
> classificatory

The package implements the functions described below.

Binary features. Binary features are derived features obtained as a result of representing the original feature domain as a set of binary values. For instance, if an integer feature X has the values 1..5 (i.e. its cardinality is 5), then there are three derived binary features X.1, X.2, X.3 having the following values depending on the value of X:

> X | X.1 | X.2 | X.3
> 1 | 0 | 0 | 0
> 2 | 0 | 0 | 1
> 3 | 0 | 1 | 0
> 4 | 0 | 1 | 1
> 5 | 1 | 0 | 0

And the mapping of the values of X.i to the subsets of X values is:

> X.i | 0 | 1
> X.1 | [1,4] | {5}
> X.2 | {1,2,5} | {3,4}
> X.3 | {1,3,5} | {2,4}

The binary features are dependent not only from the source feature. The features corresponding to the lower bits depend on the features of the higher order. Thus the functions querying the possibility or necessity may have side effects. For instance, let's the feature X has the following distributions of the possibilities and necessities:

> X | Possibility | Necessity
> 1 | 1.0 | 0.5
> 2 | 1.0 | 1.0
> 3 | 0.0 | 0.0
> 4 | 0.0 | 0.0
> 5 | 0.0 | 0.0

The highest order binary feature X.1 does not depend on other binary features, so its possibility and necessity will be:

> X.1 | Possibility | Necessity
> 0 | 1.0 = Px|[1,4] | 0.0 = Nx|[1,4]
> 1 | 0.0 = Px|{5} | 0.0 = Nx|{5}

The possibility and necessity of a domain value of X.2 depends on the realization of X.1:

> X.2 | X.2|X.1=0 | X.2|X.1=1
> Possibility | Necessity | Possibility | Necessity
> 0 | 1.0 = Px|[1,2] | 0.5 = Nx|[1,2] | 0.0 = Px|{5} | 0.0 = Nx|{5}
> 1 | 0.0 = Px|[3,4] | 0.0 = Nx|[3,4] | 0.0 = Px|{Ø} | 1.0 = Nx|{Ø}

> `function Create_Binary (Feature : Feature_Handle)
> return Bounded_Array;
> function Create_Binary (Feature : Feature_Handle)
> return Feature_Array;`

This function creates all possible derived binary features of the feature specified by the parameter Feature. The newly created features will have names of the source feature with the suffix ".n" added, where n is the order of the created feature. The domain set of a binary feature is {0,1}. There are n different binary features of a source feature, where n is binary logarithm of the feature domain cardinality. The first binary feature has the value of the highest order bit of the binary representation of the source feature domain value index. The result is either of the type Bounded_Array or Feature_Array, an array of handles to created features. Constraint_Error is propagated if Feature is invalid.

> `function Create_Binary
> ( Name : String;
> Feature : Feature_Handle
> ) return Feature_Handle;`

This function provides an option to create derived binary features one by one. When Feature indicates a non-binary feature, the result is the first binary feature derived from it. When feature indicates a binary feature, the result is the binary feature second to it. The parameter Name specifies the name of the result. End_Error is propagated when the feature cannot be created because Feature is already the last possible binary feature. Constraint_Error is propagated if the handle Feature is invalid. Handles to binary features have some specific operations defined in Fuzzy.Feature.Binary.

> `function Create_Binary
> ( Name : String;
> Feature : Feature_Handle
> Bit_Position : Natural
> ) return Feature_Handle;`

This function creates a single derived binary feature. The parameter Name specifies the name of the result. The parameter Bit_Position specifies the bit of the domain value position of the. The position of the most significant bit is 0. End_Error is propagated when the feature cannot be created because Bit_Position is bigger than the least significant bit. Constraint_Error is propagated if Feature is invalid.

Mutually independent binary features. The following functions construct binary features which are all similar to the described above ones, but are dependent only on the source, so that the binary features derived from the same source are mutually independent.

> `function Create_Independent_Binary (Feature : Feature_Handle)
> return Bounded_Array;
> function Create_Independent_Binary (Feature : Feature_Handle)
> return Feature_Array;`

This function is similar to the function Create_Binary. The result is an array of all possible independent binary features derived from Feature. It has the type of either Bounded_Array or Feature_Array. Constraint_Error is propagated if Feature is invalid.

> `function Create_Independent_Binary
> ( Name : String;
> Feature : Feature_Handle
> ) return Feature_Handle;`

This function creates derived independent binary features one by one. When Feature indicates a non-binary feature, the result is the first independent binary feature derived from it. When feature indicates a binary feature, which can be normal or independent one, then the result is the independent binary feature second to it. The parameter Name specifies the name of the result. End_Error is propagated when the feature cannot be created because Feature is already the last possible binary feature. Constraint_Error is propagated if the handle Feature is invalid. Handles to independent binary features have some specific operations defined in Fuzzy.Feature.Binary.Mutually_Independent.

> `function Create_Independent_Binary
> ( Name : String;
> Feature : Feature_Handle
> Bit_Position : Natural
> ) return Feature_Handle;`

This function creates a single derived binary feature. The parameter Name specifies the name of the result. The parameter Bit_Position specifies the bit of the domain value position of the. The position of the most significant bit is 0. End_Error is propagated when the feature cannot be created because Bit_Position is bigger than the least significant bit. Constraint_Error is propagated if Feature is invalid.

Classificatory features. A classificatory feature encapsulates some classifier which result is the value of the feature. Thus the domain value set of a classificatory feature is same as one of the class-feature of the classifier. When a classificatory feature image is requested, first it is checked whether it is present in the given example of the training set. If so, the image from the training set is returned. Otherwise, the classifier is applied to the example and the classification result determines the image.

> `function Create_Classificatory
> ( Name : String;
> Classifier : Classifier_Handle;
> Generalize : Generalization_Mode := Linear;
> Threshold : Confidence := Confidence'First
> ) return Feature_Handle;`

This function creates a classificatory feature. The parameter Name specifies the feature name. The parameter Classifier is a handle to one used in classifications. The parameter Generalize specifies a generalization advise for the classifier as used by the procedure Classify. Another parameter influencing classifications is Threshold; which specifies the threshold applied during classifications. Constraint_Error is propagated when Classifier is invalid. Handles to classificatory features have specific operations defined in Fuzzy.Feature.Classificatory. Features and classifiers are complementary. An operation reverse to creation of a feature from a classifier is construction of an identity classifier.

Discrete features

> `function Create_Discrete (Name : String; Domain : String)
> return Feature_Handle;`

This function creates a discrete feature. The parameter Name is the name of the newly created feature. The parameter Domain is the list of feature domain element names separated by commas. A name should start with a letter and contain only letters, digits, underline and spaces. The last character cannot be a space or underline. If a space or underline appears the next character shall differ. Commas in Domain can be surrounded by spaces and tabs. The whole string Domain shall be matched. Otherwise, Data_Error is propagated. It is also propagated if Name contains duplicated element names. End_Error is propagated if Domain contains no valid element name.

> `function Create_Discrete
> ( Name : String;
> Domain : Domain_Description'Class
> ) return Feature_Handle;`

This function is used to create a feature object. The parameter Name is the name of the newly created feature. The result is the handle to the created feature. The parameter Domain defines the feature domain. It has the type Domain_Description. Constraint_Error is propagated when Domain is empty.

Floating-point interval features. Floating-point features have a discrete domain consisting of intervals of dimensioned floating-point numbers based on the type Domain_Float (defined in the package Fuzzy.Feature.Domain_Floats.)

> `function Create_Float
> ( Name : String;
> Cardinality : Positive;
> From : Domain_Float;
> To : Domain_Float;
> Scale : Measure := Np;
> ) return Feature_Handle;
> function Create_Float
> ( Name : String;
> Cardinality : Positive;
> From : Domain_Float;
> To : Domain_Float;
> Scale : String;
> Mode : Code_Set := UTF8_Set
> ) return Feature_Handle;`

These functions create a floating-point interval feature. These functions have the same parameters and functionality of Create from Fuzzy.Feature.Float_Handle, which also provides some operations specific to floating-point interval features.

Floating-point linguistic features. A linguistic feature is a discrete feature with a set of linguistic variables as the domain. The variables in the set are built over floating-point numbers based on the type Domain_Float (defined in the package Fuzzy.Feature.Domain_Floats.)

> `function Create_Linguistic
> ( Name : String;
> Domain : String / Linguistic_Set;
> Scale : Measure := Np
> ) return Feature_Handle;
> function Create_Linguistic
> ( Name : String;
> Domain : String / Linguistic_Set;
> Scale : String;
> Mode : Code_Set := UTF8_Set
> ) return Feature_Handle;`

These functions create a floating-point linguistic feature. These functions have the same parameters and functionality of Create from Fuzzy.Feature.Linguistic_Handle.

Floating-point isosceles trapezoid features. A linguistic feature is a discrete feature with a set of linguistic variables as the domain. The variables in the set are built over floating-point numbers based on the type Domain_Float (defined in the package Fuzzy.Feature.Domain_Floats.)

> `function Create_Isosceles_Trapezoids
> ( Name : String;
> Cardinality : Positive;
> From : Domain_Float;
> To : Domain_Float;
> Shoulder : Domain_Float;
> Scale : Measure := Np
> ) return Feature_Handle;
> function Create_Isosceles_Trapezoids
> ( Name : String;
> Cardinality : Positive;
> From : Domain_Float;
> To : Domain_Float;
> Shoulder : Domain_Float;
> Scale : String;
> Mode : Code_Set := UTF8_Set
> ) return Feature_Handle;`

These functions create a floating-point linguistic feature. These functions have the same parameters and functionality of Create from Fuzzy.Feature.Isosceles_Trapezoids_Handle.

Floating-point output features. Often a fuzzy subsystem is integrated into a larger system, in which fuzzy outputs need to be converted into crisp values, for example to be used in the actuators of a control system. This process is called defuzzification. Because defuzzification is ambiguous and cannot be performed in general, its implementation highly depends on the application domain.

> `function Create_Output
> ( Name : String;
> Feature : Feature_Handle;
> Method : Defuzzifier_Handle;
> Default : Measure
> ) return Feature_Handle;`

This function creates a floating-point output feature. It has the same parameters and functionality of Create from Fuzzy.Feature.Output_Handle, which also provides some operations specific to floating-point output features. The defuzzificator factories can be found in its children packages.

Integer features. Integer features have a set of integer singletons as the domain. The integer type used

> `function Create_Integer
> ( Name : String;
> From : Domain_Integer;
> To : Domain_Integer
> ) return Feature_Handle;`

This function creates an integer feature. It has the same parameters and functionality of Create from Fuzzy.Feature.Integer_Handle, which also provides some operations specific to integer features based on singletons.

#### 2.3.4. String edit

The package Fuzzy.Feature.Handle.Edit provides simple string I/O facilities. The values of a feature can be get from and put into a string. All subroutines are available for both the domain value ranges, fuzzy subsets of the domain, intuitionistic subsets and classification of the domain. The following input subroutines are provided by the package:

> `procedure Get
> ( Source : String;
> Pointer : in out Integer;
> Feature : Feature_Handle;
> Value : out Interval;
> Parameters : Input_Parameters'Class := Input_Defaults
> );
> procedure Get
> ( Source : String;
> Pointer : in out Integer;
> Feature : Feature_Handle;
> Value : out Set``;
> Parameters : Input_Parameters'Class := Input_Defaults
> );
> procedure Get
> ( Source : String;
> Pointer : in out Integer;
> Value : out Intuitionistic.Set``;
> Parameters : Input_Parameters'Class := Input_Defaults
> );
> ` `procedure Get
> ( Source : String;
> Pointer : in out Integer;
> Value : out Intuitionistic.Classification;
> Parameters : Input_Parameters'Class := Input_Defaults
> );`

These procedures get a feature value from the string Source. The process starts from Source (Pointer). Pointer is advanced to the string position following the value. A feature value can be an interval of domain values, a fuzzy subset, a fuzzy intuitionistic subset or an intuitionistic classification of the domain. The cardinality of the feature and of the parameter Value shall be same. Otherwise, Constraint_Error is propagated. The fields of Parameters control the way the feature domain values are input. Parameters has the type Input_Parameters defined in the package Fuzzy.Feature.

Input of intervals. The syntax of a feature domain values range of the feature depends on the feature. Usually it is:

> `<interval>` | `::=` | `<value>[{..|...}<value>]`

Where the syntax of `<value>` is determined by the feature. For a discrete or linguistic feature, `<value>` is the name of a domain point element. For an integer feature it is a decimal number etc. Ellipsis can be surrounded by spaces and tabulations. In the slice format dimensioned can be both bounds, the upper bound or none of them. When the upper bound is dimensioned then this dimension is applied to the both bounds treated as an interval.

Floating-point features additionally allow the mathematical notation of intervals:

> > `[<value>,<value>] |
> > [<value>,<value>[ |
> > ]<value>,<value>] |
> > ]<value>,<value>[`

> Floating-point feature values are dimensioned. In the interval format either both bounds are dimensioned or a dimension can be specified following the interval. In this case it is applied to the interval as a whole. Spaces and tabs can be used as separators. The examples of valid interval specifications are:

> > `[1°C, 2°C]` |  | An interval of temperatures from 1°C to 2°C
> > `[1, 2]°C` |  | The same interval
> > `[1,2] [°C]` |  | The same interval with the dimension put in []-brackets

Isosceles trapezoid features additionally allow the following syntax of trapezoids:

> > `/<value>,<value>\ |
> > ]<value>\ |
> > /<value>[ |
> > ][`

> The trapezoid's bounds are defined as ones where the truth value is 0.5. Note that the slope is defined by the feature, so any trapezoid can be uniquely defined by its bounds. Similarly a shoulder can be defined by single bound .The values in this syntax can be dimensioned. In the interval format either both bounds are dimensioned or a dimension can be specified following the interval. In this case it is applied to the interval as a whole. Dimension is never specified for `][`. Spaces and tabs can be used as separators. The examples of valid trapezoid specifications are:

> > `/1°C, 2°C\` |  | A trapezoid of temperatures from 1°C to 2°C. The truth value in 1°C and 2°C is 0.5.
> > /`1, 2\°C` |  | The same trapezoid
> > `/1,2\ [°C]` |  | The same trapezoid with the dimension put in []-brackets
> > `]2\°C` |  | :Left shoulder reaching truth value of 0.5 in 2°C

Floating-point, linguistic, isosceles trapezoid features additionally allow the variable syntax, when the accumulated domain of the feature is the set of real numbers. The syntax of a variable is:

> `<variable>` | `::=` | `[->] <item> [ {,|->} <variable>] [->]`
> `<item>` | `::=` | `<value>[{..|...}<value>] [:<level>]`

> See Fizzy.Linguistics.Edit for further information. Dimension specification may follow the variable.

The following are the examples of valid slice specifications:

> `1°C..2°C` |  | An interval of temperatures from 1°C to 2°C
> `1..2°C` |  | The same interval
> `1..2 [°C]` |  | The same interval with the dimension put in []-brackets
> `-2..-1 [-1°C]` |  | The same interval, the result of [-2,-1]·(-1°C)
> `1°C` |  | One temperature point

When no dimension in any form is specified, it is assumed to be one of the feature scale. Except for the case when the dimension is required by Parameters.Get_Units field of the input parameters. No dimension is ever required if the feature scale is 1 SI. The parameter Parameters.Quote_Units when true requires any dimension specification to be put in []-brackets. This can be used to avoid ambiguities in space separated input. The syntax of a unit specification is one of a dimensioned value as described in Measures_Universal_Edit. The field Parameters.Mode specifies the character set used. Spaces and tabulations may surround commas, ellipsis, dimension specifications in brackets. Floating-point numeric may contain a decimal point and decimal exponent part, for further information see the package Strings_Edit.Float_Edit. Integer numeric values can be input in either of 2..16 base. Parameters.Base controls this behavior. Note that the base specification itself does not appear in the input.

Input of fuzzy sets. The syntax of a fuzzy domain subset is:

> `<set>` | `::=` | `<item>[,<set>]`
> `<item>` | `::=` | `<interval>[:<confidence-level>`

Here `<interval>` has the syntax described above. The syntax of `<confidence-level>` is described in the package Confidence_Factors.Edit. Spaces and tabulations may surround commas and colons.

Input of intuitionistic fuzzy sets and classifications. The syntax of both is:

> `<classification>` | `::=` | `<item>[,<classification>]`
> `<item>` | `::=` | `<interval>[:<possibility>[:<necessity>]]`
> `<possibility>` | `::=` | `<confidence-level>`
> `<necessity>` | `::=` | `<confidence-level>`

When the specifications of the possibility and the necessity are omitted, they are assumed to be of Parameters.Default. If only the necessity is missing it is assumed equal to the given possibility combined by and with Parameters.Default.Necessity. If the specified intervals overlap, then the maximum of the confidence levels for necessities and possibilities is chosen for the overlapping domain values. For linguistic features `<interval>` can also be specified in a numeric form with bounds specified by numbers rather than names of the corresponding linguistic variables. In this case, however, neither the possibility nor the necessity specification is allowed. Examples:

> `1,2,6..9` |  | Contains 1,2,6,7,8,9 with 1:1 (true)
> `Red:1,Blue:1.0:0.3` |  | Contains Blue with 1.0:0.3 and Red with 1:1
> `-10.5..10.5, High` |  | For a linguistic feature the result contains interval [-10.5, 10.5] and the value of the linguistic variable High

Exceptions
Constraint_Error | Invalid handle Feature, a domain value is not in range
Data_Error | Syntax error
End_Error | Nothing is recognized
Layout_Error | Pointer is not in the range Source'First..Source'Last+1
Unit_Error | Error in unit specification, dimension specification is omitted where it is required

> `function Value
> ( Source : String;
> Feature : Feature_Handle;
> Parameters : Input_Parameters'Class := Input_Defaults
> ) return Interval;
> function Value
> ( Source : String;
> Feature : Feature_Handle;
> Parameters : Input_Parameters'Class := Input_Defaults
> ) return Set;
> function Value
> ( Source : String;
> Feature : Feature_Handle;
> Parameters : Input_Parameters'Class := Input_Defaults
> ) return Intuitionistic.Set;
> function Value
> ( Source : String;
> Feature : Feature_Handle;
> Parameters : Input_Parameters'Class := Input_Defaults
> ) return Intuitionistic.Classification;`

These functions are simplified versions of the corresponding Gets. They convert the string Source to a value of Feature. The whole string shall be matched. Otherwise Data_Error is propagated.

Exceptions
Constraint_Error | Invalid handle Feature, the value is not in range
Data_Error | Syntax error
End_Error | Nothing is recognized

The output subroutines of the package are:

> `procedure Put
> ( Destination : in out String;
> Pointer : in out Integer;
> Feature : Feature_Handle;
> Value : Interval;
> Parameters : Output_Parameters'Class := Output_Defaults
> Field : Natural := 0;
> Justify : Alignment := Left;
> Fill : Character := ' '
> );
> procedure Put
> ( ... -- Other parameters are same as above
> Value : Domain_Subset;
> ` `...
> );
> procedure Put
> ( ... -- Other parameters are same as above
> Value : Set;
> ...
> );
> procedure Put
> ( ... -- Other parameters are same as above
> Value : Intuitionistic.Set;
> ...
> );
> procedure Put
> ( ... -- Other parameters are same as above
> Value : Intuitionistic.Classification;
> ...
> );`

These procedures place a feature value specified by the parameter Value into the output string Destination. The parameter Value is either an interval, a crisp domain subset (Domain_Subset), a fuzzy subset, an intuitionistic fuzzy set or an intuitionistic classification of the feature domain set. The string is written starting from Destination (Pointer). Pointer is then advanced to point after the end of the output field. The parameter Field determines the width of the output field. Zero width means the minimal possible width. If Field is not zero Justify determines the way the value should be aligned within the output field. The parameter Fill is then the fill character. The cardinality of the feature and of the parameter Value should be same. Otherwise, Constraint_Error is propagated. The output contains only one value if the interval consists of only it. Otherwise both the left and right bounds are output. Fields of Parameters determine the way feature values are output. It has the type Output_Parameters:

- Integer feature values are output in the base specified by Parameters.Base;
- The precision of floating-point values is controlled by the fields Parameters.Abs_Small and Parameters.Rel_Small (see Strings_Edit.Float_Edit for further information);
- Positive numbers can be output with a forwarding +, as specified by Parameters.Put_Plus;
- Dimension used is one of the feature scale, unless Parameters.Use_SI requires SI units;
- Dimension specification is used if Parameters.Put_Units is true. It is put in []-brackets if Parameters.Quote_Units is true. Derived units are allowed if Parameters.Use_Derived is true. A SI specification of 1 SI (dimensionless) is never output;
- Parameters.Mode specifies the character set used for SI units specifications It is ignored if the feature scale was specified as a text, which is then used for output (provided that Parameters.Use_SI is false);
- Parameters.Default determines the way truth values can be omitted. If a possibility / necessity pair equals to Parameters. Default it is omitted. If the necessity equals to the possibility and Parameters.Default.Necessity combined using and, then only the possibility is output.

Values of floating-point features are always output as intervals.

Exceptions
Constraint_Error | Invalid handle Feature or illegal interval Value (Value.From > Value.To)
Layout_Error | The value of Pointer is not in the range Destination'Range or there is no room for the output

> `function Image
> ( Feature : Feature_Handle;
> Value : Interval;
> Parameters : Output_Parameters'Class := Output_Defaults
> ) return String;
> function Image
> ( Feature : Feature_Handle;
> Value : Set;
> Parameters : Output_Parameters'Class := Output_Defaults
> ) return String;
> function Image
> ( Feature : Feature_Handle;
> Value : Domain_Subset;
> Parameters : Output_Parameters'Class := Output_Defaults
> ) return String;
> function Image
> ( Feature : Feature_Handle;
> Value : Intuitionistic.Set;
> Parameters : Output_Parameters'Class := Output_Defaults
> ) return String;
> function Image
> ( Feature : Feature_Handle;
> Value : Intuitionistic.Classification;
> Parameters : Output_Parameters'Class := Output_Defaults
> ) return String;`

These functions convert a feature value range (the parameter Value) to string. They are simplified versions of corresponding Put.

Exceptions
Constraint_Error | Invalid handle Feature or illegal interval Value (Value.From > Value.To)

The package Fuzzy.Feature.Handle.Edit defines two constants used as the defaults for the input and output parameters:

> `Input_Defaults : constant Input_Parameters :=
> ( Base => 10,
> Default => Certain_True,
> Get_Units => False,
> Mode => UTF8_Set,
> Quote_Units => False
> );
> Output_Defaults : constant Output_Parameters :=
> ( Abs_Small =>-MaxSmall,
> Base => 10,
> Default => Certain_True,
> Mode => UTF8_Set,
> Rel_Small => MaxSmall,
> Put_Plus => False,
> Put_Units => False,
> Quote_Units => False,
> Use_Derived => True,
> Use_SI => False
> );`

> `procedure Get_Domain
> ( Feature : Feature_Handle;
> Domain : out Domain_Description'Class;
> Parameters : Output_Parameters'Class := Output_Defaults
> );`

These procedure gets a domain description for Feature. The description is returned in the parameter Domain of Domain_Description type. Note that numeric features may have illegal names of the domain values in Domain. The formatting of the domain names is determined by Parameters. Constraint_Error is propagated when Feature is an invalid handle.

#### 2.3.5. Output in HTML format

The package Fuzzy.Feature.Handle.HTML provides output of feature values in the HTML format. Each subprogram of the package has two variants one for an arbitrary file, another is for the standard output file. The output is controlled by the parameters set into a value of HTML_Parameters'Class type. The type is defined in the package Fuzzy.Feature.HTML as follows:

> `type HTML_Parameters is new Output_Parameters with record
> Resolution : Positive := 50;
> Background : Color := (16#FF#, 16#FF#, 16#FF#);
> Conflicting_Bar : Color := (16#FF#, 16#00#, 16#00#);
> Limits : Color := (16#00#, 16#00#, 16#00#);
> Necessity_Bar : Color := (16#A0#, 16#A0#, 16#00#);
> Possibility_Bar : Color := (16#00#, 16#80#, 16#00#);
> Title : Color := (16#A0#, 16#A0#, 16#FF#);
> UTF8_Error : UTF8_Code_Point := Character'Pos ('?');
> end record;`

It adds the following HTML-output specific fields:

- Background defines the background color;
- Conflicting_Bar is the color of the necessity truth values greater than ones of the possibility;
- Limits is the color of the truth values limits;
- Necessity_Bar is the color of the necessity lesser than the possibility;
- Possibility_Bar is the color of the possibility greater than the necessity;
- Resolution is the width of the truth value 1 measured in the with of `'|'`;
- Title is the background color of the table titles;
- UTF8_Error is the code point used to replace improperly encoded UTF-8 characters.

The package Fuzzy.Feature.Handle.HTML defines the constant:

> `HTML_Defaults : constant HTML_Parameters :=
> ( Abs_Small =>-MaxSmall,
> Background =>` `16#FF#, 16#FF#, 16#FF#)``,
> Base => 10,
> Conflicting_Bar =>` `(16#FF#, 16#00#, 16#00#)``,
> Default => Certain_True,
> Mode => Units.UTF8_Set,
> Limits =>` `(16#00#, 16#00#, 16#00#)``,
> Necessity_Bar =>` `(16#A0#, 16#A0#, 16#00#)``,
> Rel_Small => MaxSmall,
> Resolution => 50,
> Possibility_Bar =>` `(16#00#, 16#80#, 16#00#)``,
> Put_Plus => False,
> Put_Units => False,
> Quote_Units => True,
> Title =>` `(16#A0#, 16#A0#, 16#FF#)``,
> Use_Derived => True,
> Use_SI => False,
> UTF8_Error => Character'Pos ('?');
> );`

Intuitionistic classifications and sets are output using:

> `procedure Put
> ( File : File_Type;
> Feature : Feature_Handle;
> Value : Intuitionisitc.Set;
> Parameters : HTML_Parameters'Class := HTML_Defaults
> );
> procedure Put
> ( File : File_Type;
> Feature : Feature_Handle;
> Value : Intuitionisitc.Classification;
> Parameters : HTML_Parameters'Class := HTML_Defaults
> );`

or for the standard output:

> `procedure Put
> ( Feature : Feature_Handle;
> Value : Intuitionisitc.Set;
> Parameters : HTML_Parameters'Class := HTML_Defaults
> );
> procedure Put
> ( Feature : Feature_Handle;
> Value : Intuitionisitc.Classification;
> Parameters : HTML_Parameters'Class := HTML_Defaults
> );`

These procedures write a Value of the feature Feature in the HTML format. An output may look like:

> Red | ||||||||||||||||||||||||||||||||||||||||||||||||||||
> Green | ||||||||||||||||||||||||||||||||||||||||||||||||||||
> Blue | ||||||||||||||||||||||||||||||||||||||||||||||||||||
> Yellow | ||||||||||||||||||||||||||||||||||||||||||||||||||||
> Pink | ||||||||||||||||||||||||||||||||||||||||||||||||||||
> Cyan | ||||||||||||||||||||||||||||||||||||||||||||||||||||
> Brown | ||||||||||||||||||||||||||||||||||||||||||||||||||||
> Black | ||||||||||||||||||||||||||||||||||||||||||||||||||||
> White | ||||||||||||||||||||||||||||||||||||||||||||||||||||

It has the format of a table. The first column contains the feature domain values. In the shown example the feature is a discrete feature with the domain set Red, Green, ... , White. The second column represents the pair of distributions of the confidence, i.e. two fuzzy sets. The width of the second column is determined by Parameter.Resolution which is the number of vertical | strokes used to represent the truth value 1.0. One set is the distribution of necessities indicated by the colored bar which color is specified by the parameter Parameters.Necessity_Bar. The distribution of possibilities is indicated by the color Parameters.Possibility_Bar. For a normal value possibility is always greater than the necessity. If it is not so, it is conflicting or inconsistent. In this case the color Parameters.Conflicting_Bar is used to indicate the part of the necessity bar exceeding the possibility. The color Parameters.Background is used for the background. The color Parameters.Limits is used for the strokes indicating 0 and 1 levels of confidence. Parameters.Mode determines the character set of the feature domain set values, such as the word Brown in the example given. The character set ASCII_Set is equivalent to Latin1_Set. The character set UTF8_Set assumes that the values are valid UTF-8 encoded strings. If they are not, all illegal characters are represented by Parameters.UTF8_Error. Constraint_Error is propagated when the cardinality of the feature is not equal to the cardinality of the realization. I/O exceptions may propagate if file output fails.

> `procedure Put
> ( File : File_Type;
> Feature : Feature_Handle;
> Value : Set;
> Parameters : HTML_Parameters'Class := HTML_Defaults
> );`

or for the standard output:

> `procedure Put
> ( Feature : Feature_Handle;
> Value : Set;
> Parameters : HTML_Parameters'Class := HTML_Defaults
> );`

These procedures write a fuzzy subset Value of the domain set of Feature in the HTML format. An output may look like:

> Red | ||||||||||||||||||||||||||||||||||||||||||||||||||||
> Green | ||||||||||||||||||||||||||||||||||||||||||||||||||||
> Blue | ||||||||||||||||||||||||||||||||||||||||||||||||||||
> Yellow | ||||||||||||||||||||||||||||||||||||||||||||||||||||
> Pink | ||||||||||||||||||||||||||||||||||||||||||||||||||||
> Cyan | ||||||||||||||||||||||||||||||||||||||||||||||||||||
> Brown | ||||||||||||||||||||||||||||||||||||||||||||||||||||
> Black | ||||||||||||||||||||||||||||||||||||||||||||||||||||
> White | ||||||||||||||||||||||||||||||||||||||||||||||||||||

Here only one distribution is shown. The color of the bar used to indicate the level of confidence is specified by the parameter Parameters.Possibility_Bar. The color Parameters.Background is used for the background. The color Parameters.Limits is used for the strokes indicating 0 and 1 levels of confidence. The type Set of the parameter Value is defined in the package Fuzzy. Parameters.Mode determines the character set of the feature values. The character set ASCII_Set is equivalent to Latin1_Set. The character set UTF8_Set assumes that the values are valid UTF-8 encoded strings. If they are not, all illegal characters are represented by Parameters.UTF8_Error. Constraint_Error is propagated when the cardinality of the feature is not equal to the cardinality of the realization or Feature is an invalid handle. I/O exceptions may propagate if file output fails.

#### 2.3.6. Handles to integer features

Integer features have the domain built out of integer sets. The sets composing the domain usually are singletons, but in the most general case, they can be any fuzzy subsets of the set of integer numbers. A typical integer feature takes values from some range of integer values {i1, i2, ..., in}.

Domain integer type. Domain_Integer is the integer type on which the domain is based. This type is defined in the package Fuzzy.Feature.Domain_Integers. This package also provides corresponding interval and fuzzy numeric types. These types can be referred as:

- Domain_Integer from the package Fuzzy.Feature.Domain_Integers;
- Interval from the package Integer_Intervals defined in Fuzzy.Feature.Domain_Integers;
- Fuzzy_Integer from the package Fuzzy_Integers defined in Fuzzy.Feature.Domain_Integers.

The package Fuzzy.Feature.Domain_Integers instantiates the following packages useful for handling domain integer and related types:

Package | Instance of | Provides
Fuzzy_Integers | Fuzzy.Integers | Integer fuzzy numbers. The type Fuzzy_Integer
Integer_Edit | Strings_Edit.Integer_Edit | String I/O for integer numbers
Integer_Intervals | Intervals.Integers | Integer intervals. The type Interval.

It is an instance of the package Fuzzy.Feature.Generic_Domain_Integer.

Operations on integer features. The package Fuzzy.Feature.Domain_Integer_Handle provides operations supported by all integer features based on Domain_Integer:

> `function Classify
> ( Feature : Feature_Handle;
> Value : Domain_Integer
> ) return Fuzzy.Intuitionistic.Classification;
> function Classify
> ( Feature : Feature_Handle;
> Value : Interval
> ) return Fuzzy.Intuitionistic.Classification;
> function Classify
> ( Feature : Feature_Handle;
> Value : Fuzzy_Integer
> ) return Fuzzy.Intuitionistic.Classification;`

These functions return a classification of Value. The classification tells how possible and necessary Value is contained by the subsets of the domain set of Feature. The parameter Feature is a handle to integer feature. The parameter Value can be a plain number, an integer interval or a fuzzy integer number. The cardinality of the result is one of the feature. Constraint_Error is propagated when Feature is not a valid handle or not a handle to an integer feature.

> `function Is_Domain_Integer (Feature : Feature_Handle)
> return Boolean;;`

This function returns true if Feature is a valid handle to an integer feature.

> `function To_Set
> ( Feature : Feature_Handle;
> Value : Domain_Integer
> ) return Fuzzy.Intuitionistic.Set;
> function To_Set
> ( Feature : Feature_Handle;
> Value : Interval
> ) return Fuzzy.Intuitionistic.Set;
> function To_Set
> ( Feature : Feature_Handle;
> Value : Fuzzy_Integer
> ) return Fuzzy.Intuitionistic.Set;`

These functions return an intuitionistic fuzzy set corresponding to Value. It tells how possible and necessary is that Value contains the subsets of the feature domain set. The parameter Value can be a plain number, an integer interval or an integer fuzzy number. The cardinality of the result is one of the feature. Constraint_Error is propagated when the parameter Feature is not a valid handle to an integer feature.

The package Fuzzy.Feature.Domain_Integer_Handle is an instance of the generic package Fuzzy.Feature.Generic_Domain_Integer.Generic_Handle.

Integer features based on singletons. The feature domain set of these features is described by an integer range I=i1...in. The elements of the domain are integer singletons {i1},{i2}, ... , {in}. The domain set is {{i}| i∈I}. The union of the domain values (accumulated set) gives the range I.

The package Fuzzy.Feature.Integer_Handle provides implementation of the integer features of this type. It also defines the following operations:

> `function Create
> ( Name : String;
> From : Domain_Integer;
> To : Domain_Integer
> ) return Feature_Handle;`

This function creates an integer feature. The parameter Name is the name of the newly created feature. The parameters From and To determine the range of the feature domain. Its cardinality will be To - From + 1. End_Error is propagated when From>To.

> `function Get_From
> ( Feature : Feature_Handle / Feature_Object'Class
> ) return Domain_Integer;`

This function returns the lower bound of the accumulated domain set. Constraint_Error is propagated when Feature is not a valid handle to integer feature or not an object of that type.

> `function Get_To
> ( Feature : Feature_Handle / Feature_Object'Class
> ) return Domain_Integer;`

This function returns the upper bound of the accumulated domain set. Constraint_Error is propagated when Feature is not a valid handle to or not an integer feature object.

> `function Is_Integer
> ( Feature : Feature_Handle / Feature_Object'Class
> ) return Boolean;`

This function returns true if Feature is a valid handle to an integer feature object.

The package Fuzzy.Feature.Integer_Handle is an instance of the generic package Fuzzy.Feature.Generic_Domain_Integer.Generic_Integer.

#### 2.3.7. Handles to floating-point features

Real features have the domain built out of sets of dimensioned real numbers. The sets composing the domain usually are intervals or linguistic variables of other shapes.

Domain floating-point type. Domain_Float is the floating-point type on which the domain is based. This type is defined in the package Fuzzy.Feature.Domain_Floats. This package also provides corresponding interval and fuzzy numeric types. These types can be referred as:

- Domain_Float from the package Fuzzy.Feature.Domain_Floats;
- Interval from the package Float_Intervals defined in Fuzzy.Feature.Domain_Floats;
- Variable from the package Variables defined in Fuzzy.Feature.Domain_Floats is the type of compatible linguistic variables;
- Fuzzy_Float from the package Fuzzy_Floats defined in Fuzzy.Feature.Domain_Floats is the type of compatible floating-point fuzzy numbers;
- Measure from the package Float_Measures defined in Fuzzy.Feature.Domain_Floats is the type of compatible dimensioned floating-point numbers;
- Interval_Measure from the package Interval_Measures defined in Fuzzy.Feature.Domain_Floats is the type of compatible dimensioned intervals;
- Variable_Measure from the package Variable_Measures defined in Fuzzy.Feature.Domain_Floats is the type of compatible dimensioned linguistic variables;
- Fuzzy_Measure from the package Float_Measures defined in Fuzzy.Feature.Domain_Floats is the type of compatible dimensioned fuzzy floating-point numbers.

The package Fuzzy.Feature.Domain_Floats instantiates the following packages useful for handling domain floating-point numbers and related types:

Package | Instance of | Provides
Derived_Measures | Measures_Derived | Derived units
Float_Edit | Strings_Edit.Float_Edit | String I/O for floating-point numbers
Float_Intervals | Intervals.Floats | Intervals with floating-point bounds. The type Interval.
Float_Measures | Measures | Dimensioned floating-point numbers. The type Measure
Fuzzy_Floats | Fuzzy.Floats | Floating-point fuzzy numbers. The type Fuzzy_Float
Fuzzy_Measures | Fuzzy.Measures | Dimensioned fuzzy numbers. The type Fuzzy_Measure
Interval_Measures | Intervals.Measures | Dimensioned intervals. The type Interval_Measure
Irregular_Measures | Measures_Irregular | Irregular units
Measure_Edit | Measures_Universal_Edit | String I/O of dimensioned values
Measure_UTF8_Edit | Measures_UTF8_Edit | String I/O of dimensioned values, UTF-8
Variables | Fuzzy.Linguistics | Linguistic variables. The type Variable
Variable_Edit | Fuzzy.Linguistics.Edit | String I/O of linguistic variables
Variable_Measures | Fuzzy.Measures.Linguistics | Dimensioned linguistic variables. The type Variable_Measure
Variable_Measure_Sets | Fuzzy.Measures.Linguistics.Sets | Dimensioned sets of linguistic variables. The type Set_Measure
Variable_Sets | Fuzzy.Linguistics.Sets | Sets of linguistic variables. The type Linguistic_Set
Variable_Set_Edit | Fuzzy.Linguistics.Sets.Edit | String I/O of sets of linguistic variables

Fuzzy.Feature.Domain_Floats is an instance of the package Fuzzy.Feature.Generic_Domain_Float.

Operations on floating-point features. The package Fuzzy.Feature.Domain_Float_Handle provides operations specific for floating-point features:

> `function Accumulate
> ( Feature : Feature_Handle;
> Value : Fuzzy.Set
> ) return Variable_Measure;`

This function evaluates the accumulated result of a fuzzy domain subset. Value is the subset to accumulate. The accumulated result is returned as a dimensioned linguistic variable. Constraint_Error is propagated when the cardinality of Value differs from one of Feature or when Feature is not a valid handle to a floating-point feature.

> `function Classify
> ( Feature : Feature_Handle;
> Value : Measure
> ) return Fuzzy.Intuitionistic.Classification;
> function Classify
> ( Feature : Feature_Handle;
> Value : Interval_Measure
> ) return Fuzzy.Intuitionistic.Classification;
> function Classify
> ( Feature : Feature_Handle;
> Value : Fuzzy_Measure
> ) return Fuzzy.Intuitionistic.Classification;
> function Classify
> ( Feature : Feature_Handle;
> Value : Variable_Measure
> ) return Fuzzy.Intuitionistic.Classification;`

These function return a classification of Value. The classification tells how possible and necessary Value is contained by the subsets of the domain set of Feature. The parameter Feature is a handle to floating-point feature. The parameter Value can be a dimensioned number, interval, linguistic variable or fuzzy floating-point number. The cardinality of the result is one of the feature. Constraint_Error is propagated when Feature is not a valid handle or not a handle to a floating-point feature. Unit_Error is propagated when the dimension of Value is incompatible with the dimension of Feature.

> `function Get_Scale (Feature : Feature_Handle) return Measure;`

This function returns the scale of the feature values. The result is a dimensioned value which multiplies dimensionless feature values when no dimension is specified. Constraint_Error is propagated is Feature is invalid or does not refer to a floating-point feature.

> `function Get_Scale_Text
> ( Feature : Feature_Handle;
> Parameters : Output_Parameters'Class := Output_Defaults
> ) return String;`

This function returns the scale specification of the feature values. Parameters controls the result. When Parameters.Use_SI is true, or else when the feature was created with no scale string specified, the result is in SI units. Otherwise it the scale string as it was specified in upon feature creation. In the former case Parameters.Mode controls the character set to use. Additionally, Parameters.Use_Derived allows use of derived SI units. The result is an empty string if 1 SI should be the result. When the result is not empty, it is surrounded by []-brackets if Parameters.Quote_Units is true. The result can be an empty string. Constraint_Error is propagated is Feature is invalid or does not refer to a floating-point feature.

> `function Get_Unit (Feature : Feature_Handle) return Unit;`

This function returns the feature dimension. Constraint_Error is propagated is Feature is invalid or does not refer to a floating-point feature.

> `function Get_Variable
> ( Feature : Feature_Handle;
> Value : Positive
> ) return Variable_Measure;`

This function returns the feature domain set element (domain value) by its index. All variables of the domain are numbered starting from 1 up to Get_Cardinality (Feature). Thus the result the accumulated value of the singleton set corresponding to the index Value. Constraint_Error is propagated when Feature is invalid or does not refer to a floating-point feature.

> `function Is_Domain_Float (Feature : Feature_Handle)
> return Boolean;;`

This function returns true if Feature is a valid handle to a floating-point feature.

> `function Is_Domain_Linguistic (Feature : Feature_Handle)
> return Boolean;;`

This function returns true if Feature is a valid handle to a floating-point feature which has linguistic names of the domain values.

> `function To_Set
> ( Feature : Feature_Handle;
> Value : Measure
> ) return Fuzzy.Intuitionistic.Set;
> function To_Set
> ( Feature : Feature_Handle;
> Value : Interval_Measure
> ) return Fuzzy.Intuitionistic.Set;
> function To_Set
> ( Feature : Feature_Handle;
> Value : Fuzzy_Measure
> ) return Fuzzy.Intuitionistic.Set;
> function To_Set
> ( Feature : Feature_Handle;
> Value : Variable_Measure
> ) return Fuzzy.Intuitionistic.Set;;`

These functions return an intuitionistic fuzzy set corresponding to Value. It tells how possible and necessary is that Value contains the subsets of the feature domain set. The parameter Feature is a handle to floating-point feature. The parameter Value can be a dimensioned number, interval, linguistic variable or fuzzy floating-point number. The cardinality of the result is one of the feature. Constraint_Error is propagated when Feature is not a valid handle or not a handle to a floating-point feature. Unit_Error is propagated when the dimension of Value is incompatible with the dimension of Feature.

The package Fuzzy.Feature.Domain_Float_Handle is an instance of Fuzzy.Feature.Generic_Domain_Float.Generic_Handle.

Floating-point interval features. Floating-point features have a discrete domain consisting of real intervals Ii=[li, ui], such that li+1=ui. The union of the intervals (accumulated set) is again an interval:

> I = |
> n
> ∪
> i=1
> | [li, ui] | = | [l1, un]

where n is the cardinality of the feature. The package Fuzzy.Feature.Float_Handle provides an implementation of such features based on the type Domain_Float (defined in the package Fuzzy.Feature.Domain_Floats.) It provides the following operatioms:

> `function Create
> ( Name : String;
> Cardinality : Positive;
> From : Domain_Float;
> To : Domain_Float;
> Scale : Measure := Np;
> ) return Feature_Handle;
> function Create
> ( Name : String;
> Cardinality : Positive;
> From : Domain_Float;
> To : Domain_Float;
> Scale : String;
> Mode : Code_Set := UTF8_Set
> ) return Feature_Handle;`

These functions create a floating-point feature. The parameter Name is the name of the newly created feature. The parameters From and To determine the range of the accumulated feature domain in the dimension units of the feature. From is l1, To is un in the notation above. n, the number of intervals is defined by the parameter Cardinality. Each elementary interval [li, ui] has the width (To - From) / Cardinality. The parameter Scale specifies the scale used for the feature values. It can be either a dimensioned value of the type Measure or a string, which is parsed using the function Measures_Universal_Edit.Value. For example, if From = 0, To = 10 and Scale is 2°C, then the domain range is [0°C, 20°C]. The scale shall have a positive gain, Unit_Error is propagated otherwise. The parameter Mode defines the character set used to parse Scale. The type Code_Set is declared in the package Units.

Exceptions
Constraint_Error | From=To but Cardinality is not 1
End_Error | From>To
Unit_Error | Scale does not contain a recognizable unit, has syntax error, was not fully matched, Scale has zero or negative gain.

> `function Get_From (Feature : Feature_Handle / Feature_Object'Class)
> return Measure;`

This function returns the lower bound of the feature values l1. Constraint_Error is propagated is Feature is invalid or does not refer to a floating-point feature object.

> `function Get_Interval
> ( Feature : Feature_Handle / Feature_Object'Class;
> Value : Positive
> ) return Intervals_Measure;`

This function returns the interval corresponding to the index Value (1..Cardinality), i.e. [li, ui] where i is specified by Value. Constraint_Error is propagated is Feature is invalid, does not refer to a floating-point feature or Value is out of range.

> `function Get_Span (Feature : Feature_Handle / Feature_Object'Class)
> return Interval_Measure;`

This function returns the range of the feature values as a dimensioned interval, i.e. it returns I=[l1, un]. Constraint_Error is propagated is Feature is invalid or does not refer to a floating-point feature.

> `function Get_To (Feature : Feature_Handle / Feature_Object'Class)
> return Measure;`

This function returns the upper bound of the feature values un. Constraint_Error is propagated is Feature is invalid or does not refer to a floating-point feature object.

> `function Get_Unit (Feature : Feature_Handle / Feature_Object'Class)
> return Unit;`

This function returns the feature dimension. Constraint_Error is propagated is Feature is invalid or does not refer to a floating-point feature.

> `function Is_Float (Feature : Feature_Handle / Feature_Object'Class)
> return Boolean;`

This function returns true if Feature refers a floating-point feature object.

The package Fuzzy.Feature.Float_Handle is an instance of the generic package Fuzzy.Feature.Generic_Domain_Float.Generic_Float.

Floating-point linguistic features. A linguistic feature has a set of linguistic variables as the domain. The variables in the set are built over floating-point numbers based on the type Domain_Float (defined in the package Fuzzy.Feature.Domain_Floats.) A linguistic feature is similar to a discrete feature because linguistic variables can be referenced by their names. The membership function of a linguistic variable consists of points and linear segments. The package Fuzzy.Feature.Linguistic_Handle provides an implementation of linguistic floating-point features. It has the following operations defined:

> `function Create
> ( Name : String;
> Domain : String / Linguistic_Set;
> Scale : Measure := Np
> ) return Feature_Handle;
> function Create
> ( Name : String;
> Domain : String / Linguistic_Set;
> Scale : String;
> Mode : Code_Set := UTF8_Set
> ) return Feature_Handle;`

These functions create a linguistic feature. In a function the parameter Name is the name of the newly created feature. The domain specification is provided by the parameter Domain. It can be either a Linguistic_Set or a string. When Domain is String, it has the syntax of a list of elements separated by spaces and tabs. Each element correspond to a linguistic variable:

> `<list>` | `::=` | `<element>[, <list>]`
> `<element>` | `::=` | `<name>(<variable>)`

Here `<number>` has the syntax of a floating-point number. For the syntax of `<variable>` see. Round brackets, colons and commas may be surrounded by spaces and tabs. For instance the domain description of a feature for the set linguistic variables shown on the picture of outdoor temperatures would be:

> `chill (->-10->-4:0), cold (->11->17:0), tepid (3:0->8..21->28:0),
> warm (15:0->21->29->35:0), hot (25:0->28->)`

The whole contents of Domain has to be matched, Otherwise Data_Error is propagated. Data_Error is propagated on syntax errors. The parameter Scale determines the dimension of the feature values, when they viewed as real numbers. It also one of the values specified by the parameter Domain. In the example of outdoor temperatures mentioned above, Scale is 1°C. It can be given either as a dimensioned value of the type Measure or as a string, which is parsed using the function Measures_Universal_Edit.Value. The scale shall have a positive gain, Unit_Error is propagated otherwise. The parameter Mode defines the character set used to parse Scale. The type Code_Set is declared in the package Units.

Exceptions
Constraint_Error | Numeric errors while parsing string Domain.
Data_Error | Syntax error in Domain when it is a string. For Linguistic_Set the exception indicates that one of the variables has an illegal name
End_Error | Empty Domain when specified as Linguistic_Set.
Unit_Error | Scale does not contain a recognizable unit, has syntax error, was not fully matched, Scale has zero or negative gain.

> `function Is_Linguistic (Feature : Feature_Handle / Feature_Object'Class)
> return Boolean;`

This function returns true if Feature refers a linguistic feature object.

The package Fuzzy.Feature.Linguistic_Handle is an instance of Fuzzy.Feature.Generic_Domain_Float.Generic_Linguistic.

Floating-point isosceles trapezoid features represent a special case of linguistic features. The set of linguistic variables consists of isosceles trapezoids Ti and two shoulders L and R as shown on the figure below.

The union of the linguistic variables is the whole set of real numbers. The number of trapezoid variables is the feature cardinality minus two. The shoulder length is same for all linguistic variables. The package Fuzzy.Feature.Isosceles_Trapezoids_Handle provides an implementation of isosceles trapezoid features. It has the following operations defined:

> `function Create
> ( Name : String;
> Cardinality : Positive;
> From : Domain_Float;
> To : Domain_Float;
> Shoulder : Domain_Float;
> Scale : Measure := Np
> ) return Feature_Handle;
> function Create
> ( Name : String;
> Cardinality : Positive;
> From : Domain_Float;
> To : Domain_Float;
> Shoulder : Domain_Float;
> Scale : String;
> Mode : Code_Set := UTF8_Set
> ) return Feature_Handle;`

These functions create a feature. In a function the parameter Name is the name of the newly created feature. The parameter Cardinality specifies the number of linguistic variables. It cannot be less than 2, otherwise Constraint_Error is propagated. The parameters From..To determine the interval covered by trapezoids. From should be no greater than To. It can be equal to To only if Cardinality is 2. The parameter Shoulder is the shoulder length. It cannot be negative. The parameter Scale specifies the scale used for the feature values. It can be either a dimensioned value of the type Measure or a string, which is parsed using the function Measures_Universal_Edit.Value. For example, if From = 0, To = 10 and Scale is 2°C, then the domain range covered by trapezoids is [0°C, 20°C]. The scale shall have a positive gain, Unit_Error is propagated otherwise. The parameter Mode defines the character set used to parse Scale. The type Code_Set is declared in the package Units. The created feature is a linguistic one. The names of the variables are `L`, `T1`, `T2`,..., `R`. Note that when output names aren't used, instead a trapezoid notation is used as described in Fuzzy.Feature.Handle.Edit.Get. While input both the names and the trapezoid notation are acceptable.

Exceptions
Constraint_Error | Cardinality is less than 2. From is equal to To, but Cardinality is not 2. Shoulder is negative.
End_Error | From is greater than To
Unit_Error | Scale does not contain a recognizable unit, has syntax error, was not fully matched, Scale has zero or negative gain.

> `function Get_Shoulder (Feature : Feature_Handle ) return Measure;
> function Get_Shoulder (Feature : Feature_Object'Class) return Measure;`

This function returns shoulder. Constraint_Error is propagated when handle or object is invalid.

> `procedure Get_Trapezoid_Parameters
> ( Feature : Feature_Handle / Feature_Object'Class;
> From : out Measure;
> To : out Measure;
> Shoulder : out Measure
> );`

This procedure returns the parameters of Feature. From, To and Shoulder have the meaning of the corresponding parameters of Create. They are dimensioned. Constraint_Error is propagated when Feature is invalid or not of isosceles trapezoids.

> `function Is_Isosceles_Trapezoid (Feature : Feature_Handle / Feature_Object'Class)
> return Boolean;`

This function returns true if Feature refers a feature object of isosceles trapezoids.

The package Fuzzy.Feature.Isosceles Trapezoids_Handle is an instance of Fuzzy.Feature.Generic_Domain_Float.Generic_Float.Generic_Isosceles_Trapezoids.

Floating-point output features. When a floating-point feature is used in a control system as an output connected to a crisp system, like an actuator, for instance, it need to be defuzzified. I.e. the values estimated in terms of the feature domain should be converted to crisp dimensioned values using some defuzzification method associated with the feature. Such floating-point features can be built upon conventional floating-point features by adding a defuzzification method. The package Fuzzy.Feature.Output_Handle provides an implementation of floating-point output features based on the type Domain_Float. The package defines the following operations:

> `function Create
> ( Name : String;
> Feature : Feature_Handle;
> Method : Defuzzifier_Handle;
> Default : Measure
> ) return Feature_Handle;`

This function creates an output feature using another floating-point feature and a defuzzification method. The parameter Name is the feature name. Source is a handle to a feature with the floating-point domain. The newly created feature is exactly Source but also supports defuzzification by the defuzzifier which handle is Method. Default is the defuzzification default used when Method is unable to convert a fuzzy value to its crisp equivalent. Constraint_Error is propagated when any of handles is invalid or does not refer to a valid object based on the same Domain_Float type. It is also propagated on numeric errors upon dimension conversions. Unit_Error is propagated when the dimension of Default is incompatible with one of Feature.

> `function Defuzzify
> ( Feature : Feature_Handle / Feature_Object'Class;
> Value : Fuzzy.Set
> ) return Measure;
> function Defuzzify
> ( Feature : Feature_Handle / Feature_Object'Class;
> Value : Fuzzy.Set;
> Default : Measure
> ) return Measure;`

This function returns the defuzzified equivalent of Value. The result is a dimensioned number from the domain set of Feature. Constraint_Error is propagated when the cardinality of Value is not one of Feature or Feature is not a valid handle to an output feature object. The parameter Default, when used overrides the feature default. In this case Unit_Error is propagated when it has incompatible with Feature dimension.

> `function Get_Default
> ( Feature : Feature_Handle / Feature_Object'Class;
> ) return Measure;`

This function returns the defuzzification default of Feature. Constraint_Error is propagated Feature is not a valid handle to an output feature object.

> `function Get_Defuzzifier
> ( Feature : Feature_Handle / Feature_Object'Class;
> ) return Defuzzifier_Handle;`

This function returns a handle to the defuzzification method used by Feature. Constraint_Error is propagated Feature is not a valid handle to an output feature object.

> `function Get_Source
> ( Feature : Feature_Handle / Feature_Object'Class;
> Value : Fuzzy.Set
> ) return Float_Handles.Handle;`

This function returns a floating-point feature handle to the source feature. Constraint_Error is propagated when Feature is not a valid handle to an output feature object.

> `function Is_Output
> ( Feature : Feature_Handle / Feature_Object'Class
> ) return Boolean;`

This function returns true if Feature refers a linguistic output feature object.

> `procedure Set_Default
> ( Feature : in out Feature_Handle / Feature_Object'Class;
> Default : Measure
> );`

This function changes the defuzzification default of Feature to Default. Constraint_Error is propagated Feature is not a valid handle to an output feature object. It is also propagated on numeric errors upon dimension conversions. Unit_Error is propagated when the dimension of Default is incompatible with one of Feature.

> `procedure Set_Defuzzifier
> ( Feature : in out Feature_Handle / Feature_Object'Class;
> Method : Defuzzifier_Handle
> );`

This function changes the defuzzification method of Feature to Method, which is a handle to the defuzzification method to set. Constraint_Error is propagated when either Feature is not a valid handle to an output feature object or Method is not a valid handle, or Feature and Method are not build upon the same Domain_Float type.

The package Fuzzy.Feature.Output_Handle is an instance of the generic package Fuzzy.Feature.Generic_Domain_Float.Generic_Defuzzifier.Generic_Handle.Generic_Output. Defuzzifier factories are provided by the following child packages of Fuzzy.Feature.Output_Handle:

- Center_Of_Area
- Center_Of_Gravity
- Discrete_Center_Of_Gravity
- Leftmost_Max
- Rightmost_Max

### 2.4. Training sets

Training set is an object that can be dynamically created, modified and destroyed. A training set can be viewed as a table. Rows of the table are training examples. Columns are the features mentioned in the training set examples. Each cell of the table is a value of the corresponding feature (column) in the given example (row). Each value may consist of up to four feature images. They can be independently accessed for read and write. Training sets are used for learning and classification.

Note, Training set as an object does reference features of its examples. That means that if a feature gets prematurely destroyed before the set that uses it, the corresponding column is transparently removed from all examples of the set.

#### 2.4.1. Handles to training sets

The child package Fuzzy.Lecture.Handle defines the type Lecture_Handle used for general access to a training set. Initially a training set is empty. When examples are added it allocates memory needed to keep them as necessary. When a training set of different behavior is required, an Lecture_Handle is requested from the factory of training sets.

As a handle Lecture_Handle inherits a set of operations over the object handles. The operations defined on a training set handle are:

> `procedure Copy
> ( Target : in out Lecture_Handle;
> Source : Lecture_Handle;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Viewer : Indicator_Handle
> );
> procedure Copy
> ( Target : in out Lecture_Handle;
> Source : Lecture_Handle;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Viewer : access Indicator_Object'Class := Negleter'Access
> );`

This procedure adds the examples from the training set Source to the end of the training set Target. The parameters From, To define the first and the last examples to be copied from Source. To can be greater than the total number of examples. The parameter Viewer specifies an indication object. The progress of Copy is measured in percents. The parameter is either a pointer or a handle to the indicator object. The handle is allowed to be invalid. When Source is an invalid handle, the operation is void. When Target is an invalid handle, a new memory-resident training set is created as necessary.

Exceptions
Data_Error | I/O error, usually when a training set object is persistent
End_Error | Operation was aborted by the indication object.

> `procedure Delete (Lesson : in out Lecture_Handle);`

This procedure requests deletion of a Lesson. Lesson becomes an invalid handle. The object itself is deleted if possible. Nothing happens if Lesson is not a valid handle. Data_Error is propagated on I/O errors when the target training set is persistent.

> `function Get
> ( Lesson : Lecture_Handle;
> Example : Positive;
> Feature : Feature_Handle;
> Image : Fuzzy.Feature.Image_Type
> ) return Set;`

The result is the image specified by the parameter Image, of the training example Example for the feature Feature from the set Lesson. When the example or the feature is not defined in Lesson, or else, when Lesson is an invalid handle, the result is the feature domain set, i.e. all 1s.

Exceptions
Constraint_Error | Invalid handle (Feature)
Data_Error | I/O error, usually when a training set object is persistent

> `function Get
> ( Lesson : Lecture_Handle;
> Example : Positive;
> Feature : Feature_Handle
> ) return Classification;`

This function gets an intuitionistic classification of Example in terms of the domain set of Feature. A classification consists of the images has-in and has-not. When the example or the feature is not defined in Lesson, or else when Lesson is an invalid handle, the result is unknown, i.e. all possibilities are set in 1, all necessities are set in 0. Note also that there is a built-in mechanism of querying the operator for undefined values which can be used to define them as they get required.

Exceptions
Constraint_Error | Invalid handle (Feature)
Data_Error | I/O error, usually when a training set object is persistent

> `function Get_Class (Lesson : Lecture_Handle) return String;`

The training set class is known to the procedures dealing with the external persistent storage. When a set is archived, the way a it is converted to its canonical form in the persistent storage depends on the class. This function returns the training set class. It raises Constraint_Error if Lesson is invalid.

> `function Get_Examples_Number (Lesson : Lecture_Handle)
> return Natural;`

This function returns the number of examples in the set Lesson. Not all of them might be defined. The returned number can be used to enumerate examples in the set. the first example has the number 1. The result is 0 if Lesson is invalid.

> `function Get_Feature
> ( Lesson : Lecture_Handle;
> Index : Positive
> ) return Feature_Handle;`

This function returns a handle to the feature corresponding to the column Index of the set Lesson. Columns are enumerated starting with 1.

Exceptions
Constraint_Error | Index is out of range (1..Get_Features_Number)
Data_Error | I/O error, usually when a training set object is persistent

> `function Get_Features (Lesson : Lecture_Handle)
> return Bounded_Array`

A feature is used in Lesson if it defines at least one image of this feature. This function returns the array of features in the set. The order of feature handles in the array reflects their order in the set (see Get_Feature). The result is an empty array when Lesson is an invalid handle.

Exceptions
Data_Error | I/O error, usually when a training set object is persistent

> `function Get_Features_Number (Lesson : Lecture_Handle)
> return Natural;`

This function returns the total number of the features in Lesson. The features can be then enumerated using Get_Feature. The result is 0 when Lesson is an empty handle.

Exceptions
Data_Error | I/O error, usually when a training set object is persistent

> `procedure Invalidate (Lesson : in out Lecture_Handle);`

This procedure detaches handle from the training set object (if any) it points to. The result handle cannot be used to access any object. The referenced object is destroyed if it was the last handle.

> `function Is_Defined
> ( Lesson : Lecture_Handle;
> Example : Positive;
> Feature : Feature_Handle;
> Image : Fuzzy.Feature.Image_Type
> ) return Boolean;`

This function can be used to query whether an image (parameter Image) defined by the training set Lesson for the example Example and the feature Feature. Undefined images when requested are first queried from some external source when Get is used. On contrary, Is_Defined skips this querying mechanism. The result is false when Lesson is an invalid handle.

Exceptions
Constraint_Error | Invalid handle (Feature)
Data_Error | I/O error, usually when a training set object is persistent

> `function Is_Known
> ( Lesson : Lecture_Handle;
> Example : Positive;
> Feature : Feature_Handle;
> Image : Fuzzy.Feature.Image_Type
> ) return Boolean;`

This function checks if the specified image is unknown, i.e. has all values of the membership function 1. So the result is false if

> `Get (Lesson, Example, Feature, Image)`

would return all 1s. It is also false when Lesson is an invalid handle. The querying mechanism is used for undefined values.

Exceptions
Constraint_Error | Invalid handle (Feature)
Data_Error | I/O error, usually when a training set object is persistent

> `function Is_Valid (Lesson : Lecture_ Handle) return Boolean;`

This function checks whether a handle points to an object.

> `function Ptr (Lesson : Lecture_Handle) return Lecture_Object_Ptr;`

This function is used to get a pointer to the training set object a handle points to. The pointer of to the object shall be used no longer the handle it was get from exists.

> `procedure Put
> ( Lesson : in out Lecture_Handle;
> Example : Positive;
> Feature : Feature_Handle;
> Image : Fuzzy.Feature.Image_Type;
> Value : Set
> );`

This procedure sets the image specified by the parameter Image, of the training example Example for the feature Feature into the set Lesson. The value of the image is specified by the parameter Value. The procedure can be used for both creating new and modifying existing examples. When Lesson is an invalid handle a new memory-resident training set is created as necessary and Lesson is set to point to it.

Exceptions
Constraint_Error | Feature is invalid or Value has wrong cardinality
Data_Error | I/O error, usually when a training set object is persistent

> `procedure Put
> ( Lesson : in out Lecture_Handle;
> Example : Positive;
> Feature : Feature_Handle;
> Value : Classification
> );`

This procedure sets Value of Feature for Example into Lesson. The value is an intuitionistic classification of Example in Feature's domain set. A classification defines the images has-in and has-not. The procedure can be used for both creating new and modifying existing examples. When Lesson is an invalid handle a new memory-resident training set is created as necessary and Lesson is set to point to it.

Exceptions
Constraint_Error | Feature is invalid or Value has wrong cardinality
Data_Error | I/O error, usually when a training set object is persistent

> `function Ref (Lesson : Lecture_Object_Ptr)
> return Lecture_Handle;`

This function is used to get a handle from a pointer to a training set object.

> `procedure Ref
> ( Handle : in out Lecture_Handle;
> Lesson : Lecture_Object_Ptr
> );`

This procedure assigns a new training set object to handle.

> `procedure Set_Undefined
> ( Lesson : in out Lecture_Handle;
> Example : Positive;
> Feature : Feature_Handle
> );
> procedure Set_Undefined
> ( Lesson : in out Lecture_Handle;
> Feature : Feature_Handle
> );`

These procedures set the images of Feature undefined in Lesson. When the parameter Example is omitted, then all examples of the training set corresponding to Feature are reset. This has the effect that the training set will no more reference Feature (which can be removed then, if that was the last reference to it). The operation is void when Lesson is an invalid handle.

Exceptions
Constraint_Error | Invalid handle (Feature)
Data_Error | I/O error, usually when a training set object is persistent

> `procedure Set_Undefined
> ( Lesson : in out Lecture_Handle;
> Feature : Feature_Handle
> );`

These procedures set the images of Feature undefined in Lesson. When the parameter Example is omitted, then all examples of the training set corresponding to Feature are reset. This has the effect that the training set will no more reference Feature (which can be removed then, if that was the last reference to it). The operation is void when Lesson is an invalid handle.

Exceptions
Data_Error | I/O error, usually when a training set object is persistent

> `function To_Deposit_Handle (Lesson : Lecture_Handle)
> return Deposit_Handles.Handle;`

This function provides handle conversion from Lecture_Handle to a general persistent object handle. Constraint_Error is propagated when Lesson is not a valid handle.

> `function To_Lecture_Handle
> ( Lesson : Deposit_Handles.Handle
> ) return Lecture_Handle;`

This function provides a backward handle conversion from a general persistent object handle to Lecture_Handle. Constraint_Error is propagated when Lecture is not a valid handle or does not refer a training set object.

Additionally the package provides:

> `function Get_Number_Of_Lectures return Natural;`

This function returns the total number of distinct training sets.

The package Fuzzy.Lecture.Handle.Container provides the type Set, which is a set of handles to training sets. It has the same interface as the package Object.Handle.Generic_Set. It defines the type Set which represents a set of feature handles.

#### 2.4.2. Creating training sets

The package Fuzzy. Lecture.Handle.Factory provides functions for creating a new training sets.

> `function Create_Composite
> ( Mapping : Feature_To_Lecture_Map
> ) return Lecture_Handle;`

This function creates a new training set. The training set contains the examples from the sets specified in Mapping The type of Mapping is Feature_To_Lecture_Map, an array of Feature_Handle - Lecture_Handle pairs. For each feature in Mapping the training set contains the examples from the set mapped by the feature. Constraint_Error is propagated when Mapping contains invalid handles. Data_Error is propagated when it contains non-unique features.

> `function Create_Dialogue return Lecture_Handle;`

This function creates a memory-mapped training set and returns a handle to it. The created set is initially empty. The whole set of examples is memory allocated. The implementation can get an advantage if the realizations of a feature are singletons. When an undefined example is requested the user will be prompted to enter a realization of the corresponding feature using standard input and output files of Ada.Text_IO. The input is then put into the set. When the user declines input by entering an empty line, the example remains undefined.

> `function Create_Memory_Resident return Lecture_Handle;`

This function creates a memory-mapped training set and returns a handle to it. The created set is initially empty. The whole set of examples is memory allocated. This function creates a new training set and returns a handle to it. The implementation can get an advantage if the realizations of a feature are singletons.

> `function Create_Persistent
> ( Storage : Storage_Handle;
> Name : String;
> Parent : Deposit_Handle := Root_Directory
> ) return Lecture_Handle;
> function Create_Persistent
> ( Storage : Storage_Handle
> ) return Lecture_Handle;`

This function creates a new training set resident in Storage, which is a handle to a persistent storage interface object. Note that though memory resident training sets can be stored in a persistent storage as any other object, that could be done only as a whole. It might be very inefficient to store large sets in this way. Therefore persistent storage types also provide natively resident training sets. Such sets are not loaded/stored as a whole but provide I/O operations for individual training examples. So they might support sets larger than available memory. However persistent training sets could be considerably slower than the memory resident ones. The parameter Name specifies the object name there. When omitted the object is stored anonymous. Anonymous persistent objects are collected when no more used. When Name is empty, illegal or conflicts with the name of another immediate child object of Parent, then Name_Error is propagated. It is also propagated when Parent is anonymous. When name is not specified no check is made. Constraint_Error is propagated when Parent is legal but does not indicate a persistent in Storage object.

Exceptions
Constraint_Error | Invalid handle, non-persistent Parent
Data_Error | A persistent storage error
Name_Error | Name conflict, there already is a persistent object with the same name in Storage or Name is illegal, anonymous Parent
Use_Error | Storage does not support persistent set

Implementation note. The package Fuzzy.Lecture.Handle.Factory uses persistent storage factory provided by Persistent.Handle.Factory, which depends on some third party software. Refer its documentation for more information. Alternatively, if only a limited number of training set types is required by the application one can create training sets without factory, using construction functions from the corresponding implementation packages.

> `function Create_Subrange
> ( Source : Lecture_Handle;
> From : Positive;
> To : Natural := Positive'Last
> ) return Lecture_Handle;`

This function creates a new training set. The training set contains the examples From..To of Source. The parameter To may be less than From to indicate empty range. It can also be greater than the total examples number of Source. Updating the training set also does the source set. An attempt to modify the Source set outside the examples range causes Use_Error exception. Examples outside the range when read considered undefined. The training subrange set are enumerated from 1. Constraint_Error is propagated when Source is not a valid handle.

#### 2.4.3. Output in HTML format

The package Fuzzy.Lecture.Handle.HTML provides output of training sets in the HTML format. The package provides two variants of the output subprograms. One is used for an arbitrary file, another is for the standard output file:

> `procedure Put
> ( File : File_Type;
> Lesson : Lecture_Handle;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Parameters : HTML_Parameters := HTML_Defaults
> );`

or for the standard output:

> `procedure Put
> ( Lesson : Lecture_Handle;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Parameters : HTML_Parameters := HTML_Defaults
> );`

These procedures write the training set Lesson into a file in the HTML format. The output has the form of a table. The parameters From, To specify the range of the examples to be written. To can be greater than the total number of the examples in the training set. The fields of Parameters control the output. The output has the form of a table. Table rows represent training examples. Table columns contain the feature values of the examples. The values output is controlled by Parameters as described in the package Fuzzy.Feature.Handle.HTML. Additionally Parameters.Title is the background color of the table header. A unit specification appears after the feature name in the table header in all cases it is omitted after a value. In this case Parameters.Mode, Parameters.Use_SI etc control its appearance. Note that Parameters.Mode also controls all texts including the feature names. Make sure that the character set of the feature names and their scales are conform to the value Parameters.Mode.

Exceptions
Constraint_Error | Invalid handle
Data_Error | I/O error

See also example1 which illustrates HTML output of a training set.

#### 2.4.4. Text file IO

The package Fuzzy. Lecture.Handle.Text_IO provides input of training sets from text files. The training set in a file is formatted as a table which rows represent training examples and columns do the features. The syntax of input is flexible to adapt various forms of column separators and delimiters.

> `procedure Read
> ( File_Name : String;
> Lesson : in out Lecture_Handle;
> Features : Bounded_Array;
> Parameters : Read_Parameters'Class := Read_Defaults;
> Viewer : Indicator_Handle
> );
> procedure Read
> ( File_Name : String;
> Lesson : in out Lecture_Handle;
> Features : Feature_Array;
> Parameters : Read_Parameters'Class := Read_Defaults;
> Viewer : Indicator_Handle
> );
> procedure Read
> ( File_Name : String;
> Lesson : in out Lecture_Handle;
> Features : Bounded_Array;
> Parameters : Read_Parameters'Class := Read_Defaults;
> Viewer : access Indicator_Object'Class := Negleter'Access
> );
> procedure Read
> ( File_Name : String;
> Lesson : in out Lecture_Handle;
> Features : Feature_Array;
> Parameters : Read_Parameters'Class := Read_Defaults;
> Viewer : access Indicator_Object'Class := Negleter'Access
> );`

These procedures are used to read training examples from the file specified by its name (the parameter File_Name). The file is opened, read and closed by these procedures. The examples successfully read from the file are put into the training set Lesson. When Lesson is an invalid handle a new memory-resident training set is created and Lesson is set to point to it.

Note, when reading large training sets backed by a persistent storage, it is recommended to use Lecture_Update object to indicate a bulk update of the set: `declare Transaction : Lecture_Update (Ptr (Set)); begin Read ( File_Name => "training_set_file.txt", Lesson => Set, Features => Features_List ); end;`

Each training example occupies up to two lines of the file. A line consists of the classifications of features from the list specified by the parameter Features. The order of the features is defined by the list. The input is controlled by the parameters set into a value of Read_Parameters'Class type defined in the package Fuzzy.Lecture.Handle.Text_IO as an extension of the Input_Parameters:

> `type Read_Parameters is new Input_Parameters with record
> Blanks : Character_Set;
> Delimiters : Character_Set;
> Default_Example : Example_Type := Positive_Example;
> Allow_Empty_Fields : Boolean := True;
> Keywords : Table;
> end record;`

It extends Input_Parameters with the fields:

- Allow_Empty_Fields is set to allow implicitly omit feature specifications;
- Blanks is the set of blank characters;
- Default_Example is the example type used by default;
- Delimiters is the set of characters used as the delimiters between features specifications;
- Keywords is the table of keywords.

The classifications of the features in the source line are separated by the characters from the set Parameters.Blanks. The syntax of a classification depends on the feature and its input is controlled by the values of Input_Parameters as explained in the description of the package Fuzzy.Feature.Handle.Edit. Along with the feature classifications some keywords can be recognized. The type Keyword is an enumeration type defined in Fuzzy.Lecture.Handle.Text_IO:

> `type Keyword is
> ( Comment,
> Positive_Example,
> Negative_Example,
> Full_Example,
> Undefined_Example
> );
> subtype Example_Type is Keyword range Positive_Example..Full_Example;`

The keywords are:

- Comment is a combination of characters that starts a comment in the file being read. The comment continues to the end of the current file line;
- Positive_Example is a chain of characters that introduces a positive training example. In this case the feature values of the example are the classifications of the event behind the example. I.e. it defines the has-in and has-not images. This keyword or any other from the subtype Example_Type may appear at the beginning of each source line. When no example type appears it is assumed that the example will have the type specified by Parameters.Default_Example;
- Negative_Example is a chain of characters that introduces a negative training example. The feature values of the example are the classifications of the event's complement. I.e. it defines the has-out and has-not-out. Up to two lines (ignoring empty and comment lines) may define one example. In this case the first one defines the positive part and the second one the negative part of the example. In all other cases two consequent lines define two consequent training examples;
- Full_Example is a chain of characters that introduces an example that is both positive and negative, i.e. each classification of the example defines has-in=has-out and has-not=has-not-out images;
- Undefined_Example is a chain of characters that denotes an explicitly omitted feature classification.

The keywords used are defined by Parameters.Keywords, which is a table of tokens associated with a value of the type Keyword. It is allowed to have more than one chain of characters to be associated with one type of Keyword. The type of Parameters.Keywords is obtained through an instantiation of the package Tables within the package Fuzzy.Lecture.Handle.Text_IO as File_Tokens:

> `package File_Tokens is new Tables (Keyword);`

Missing classification can be specified explicitly if Parameters.Keywords contains Undefined_Example tokens. It also can be specified implicitly by omitting feature specifications. When Parameters.Delimiters is not empty then features specifications must be separated by one character from that set (and possibly an arbitrary number of characters from Parameters.Blanks). It is allowed, but not required to have one trailing delimiter after the last feature specification. Parameters.Allow_Empty_Fields additionally allows feature specifications to be considered missing when one delimiter follows another, possibly separated by Parameters.Blanks. For example, if the list of features consists of four integer features, Parameters.Allow_Empty_Fields is true and Parameters.Delimiters contains '`;`' then `1;;3` would specify the first and the third feature while the second and the fourth one would be implicitly omitted. Features specifications can be also omitted explicitly by placing a Undefined_Example keyword where a feature classification is expected. Note that when Parameters.Allow_Empty_Fields is false then each line should specify either all or none of the features. In this case the only way to omit one is to use an Undefined_Example keyword. The value Parameters have by default is

> `Read_Defaults : constant Read_Parameters :=
> ( Allow_Empty_Fields => True,
> Base => 10,
> Blanks => To_Set (' ' & HT & LF & CR & VT),
> Default => Fuzzy.Logic.Certain_True,
> Default_Example => Positive_Example,
> Delimiters => Null_Set,
> Get_Units => False,
> Mode => Units.Latin1_Set,
> Keywords => Keywords.Default,
> Quote_Units => True
> );`

It has the fields set as follows:

- Allow_Empty_Fields is set to allow features to be implicitly omitted. This includes specifying a lesser number of features values than expected and using empty fields separated by delimiters;
- Base is set to decimal integer values;
- Blanks includes space, tabulation, vertical tabulation (VT), line feed (LF), carriage return (CR). The latter two might slip through system I/O, for example when a Windows file is read under Linux. In general, line ends are determined by the operating system;
- Default is set to certain true, i.e. when truth values in a classification are omitted both are assumed to be 1. If only necessity is omitted it is assumed equal to the possibility;
- Default_Example defines the classifications to be positive training examples by default;
- Delimiters is an empty set, i.e. features values are separated only by the characters from the set Blanks;
- Get_Units is set to false, i.e. explicit unit specifications are not obligatory;
- Mode is to use the Latin-1 character set;
- Keywords is the following table:

  > Token | Keyword
  > `--` | Comment
  > `<+>` | Positive_Example
  > `<->` | Negative_Example
  > `<*>` | Full_Example
  > `*` | Undefined_Example
  > `?` | Undefined_Example

- Quote_Units is set to true to require dimension specifications to appear in []-brackets.

The parameter Viewer specifies an indication object. The progress of Read is measured in examples. See example 3 for an sample of using text I/O for reading training sets. The parameter can be either a pointer or a handle to the indication object. The handle can be invalid.

Exceptions
Constraint_Error | An invalid handle
Data_Error | I/O error
End_Error | Operation was aborted by the indication object. Some examples have been added to the set, some not

> `function Read
> ( File_Name : String;
> Features : Bounded_Array;
> Parameters : Read_Parameters'Class := Read_Defaults;
> Viewer : Indicator_Handle
> ) return Lecture_Handle;
> function Read
> ( File_Name : String;
> Features : Feature_Array;
> Parameters : Read_Parameters'Class := Read_Defaults;
> Viewer : Indicator_Handle
> ) return Lecture_Handle;
> function Read
> ( File_Name : String;
> Features : Bounded_Array;
> Parameters : Read_Parameters'Class := Read_Defaults;
> Viewer : access Indicator_Object'Class := Negleter'Access
> ) return Lecture_Handle;
> function Read
> ( File_Name : String;
> Features : Feature_Array;
> Parameters : Read_Parameters'Class := Read_Defaults;
> Viewer : access Indicator_Object'Class := Negleter'Access
> ) return v;`

These function are a simplified variant of the procedure Read. They returns the training set read from the file File_Name. The returned set is memory-mapped.

Exceptions
Constraint_Error | An invalid handle
Data_Error | I/O error
End_Error | Operation was aborted by the indication object.

> `procedure Write
> ( File_Name : String;
> Lesson : Lecture_Handle;
> Features : Bounded_Array;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Parameters : Write_Parameters'Class := Write_Defaults;
> Viewer : Indicator_Handle
> );
> procedure Write
> ( File_Name : String;
> Lesson : Lecture_Handle;
> Features : Feature_Array;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Parameters : Write_Parameters'Class := Write_Defaults;
> Viewer : Indicator_Handle
> );
> procedure Write
> ( File_Name : String;
> Lesson : Lecture_Handle;
> Features : Bounded_Array;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Parameters : Write_Parameters'Class := Write_Defaults;
> Viewer : access Indicator_Object'Class :=
> Negleter'Access
> );
> procedure Write
> ( File_Name : String;
> Lesson : Lecture_Handle;
> Features : Feature_Array;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Parameters : Write_Parameters'Class := Write_Defaults;
> Viewer : access Indicator_Object'Class :=
> Negleter'Access
> );`

These procedures are used to write training examples of a training set Lesson into a file specified by its name (the parameter File_Name). The file is created, for write and closed by these procedures. The examples are written per line. Each training example occupies up to two lines of the file. A line consists of the classifications of features from the list specified by the parameter Features. The order of the features is defined by the list. They are separated by Parameters.Delimiter. The syntax of a classification depends on the feature. Each line is prefixed by Parameters.Positive_Example and Parameters.Negative_Example depending on whether the example is positive or negative. The fields of Parameters determine the way features classifications are output as described in Fuzzy.Feature.Handle.Edit.

> `type Write_Parameters
> ( Delimiter_Length : Positive;
> Positive_Example_Length : Natural;
> Negative_Example_Length : Natural
> ) is new Output_Parameters with
> record
> Skip_Undefined : Boolean := True;
> Output_Positive : Boolean := True;
> Output_Negative : Boolean := True;
> Delimiter : String (1..Delimiter_Length);
> Positive_Example : String (1..Positive_Example_Length);
> Negative_Example : String (1..Negative_Example_Length);
> end record;`

It extends Output_Parameters with the fields:

- Delimiter and Delimiter_Length are the delimiters and the length of placed between feature values. A feature value is a fuzzy classification of the example or of its complement;
- Output_Negative is true when negative examples are to output;
- Output_Positive is true when positive examples are to output;
- Positive_Example and Positive_Example_Length are the prefix and the prefix length of the lines containing positive examples;
- Negative_Example and Negative_Example_Length are the prefix and the prefix length of the lines containing negative examples;
- Skip_Undefined instructs to ignore example that are undefined.

The value Parameters have by default is

> `Write_Defaults : constant Write_Parameters :=
> ( Abs_Small =>-MaxSmall,
> Base => 10,
> Default => Certain_True,
> Delimiter => " ",
> Delimiter_Length => 1,
> Mode => Units.Latin1_Set,
> Negative_Example => "<->",
> Negative_Example_Length => 3,
> Output_Positive => True,
> Output_Negative => True,
> Positive_Example => "<+>",
> Positive_Example_Length => 3,
> Put_Plus => False,
> Put_Units => False,
> Quote_Units => False,
> Rel_Small => MaxSmall,
> Skip_Undefined => True,
> Use_Derived => True,
> Use_SI => False
> );`

It has the fields set as follows:

- Abs_Small and Rel_Small is set to maximal precision;
- Base is set to decimal integer values;
- Default is set to certain true, i.e. when truth values in a classification are omitted both are assumed to be 1. If only necessity is omitted it is assumed equal to the possibility;
- Delimiter is space;
- Mode is to use the Latin-1 character set;
- Negative_Example is `<->`;
- Positive_Example is `<+>`;
- Put_Plus is false to drop plus sign when output positive numbers;
- Put_Units is false to drop units when output dimensioned values. Quote_Units, Use_Derived, Use_SI are irrelevant;
- Put_Plus is false to drop plus sign when output positive numbers;
- Skip_Undefined is set to true in order to ignore undefined examples.

The parameters From..To define the range of examples to output. Either may exceed the last example number. The parameter Viewer specifies an indication object. The progress of Write is measured in examples. The parameter can be either a pointer or a handle to the indication object. The handle can be invalid.

Exceptions
Constraint_Error | An invalid handle
Data_Error | I/O error
End_Error | Operation was aborted by the indication object.

#### 2.4.5. Training sets containers

The package Fuzzy.Lecture.Handle.Tables is an instantiation of the package Tables with Lecture_Handle. A training set table is map from text strings to Lecture_Handle.

#### 2.4.6. Bulk training set operations

The package Fuzzy.Lecture.Handle.Bulk provides a way to improve performance of training sets backed by a persistent storage, such as a data base:

> `type Lecture_Update (Lesson : access Lecture_Object'Class) is
> new Ada.Finalization.Limited_Controlled with private;`

The object of the type Lecture_Update is usually created before some bulk update operation, like reading the training set.

> `procedure Finalize (Transaction : in out Lecture_Update);`

This procedure is to be called upon finalization from the derive type implementation when overridden.

> `procedure Initialize (Transaction : in out Lecture_Update);`

This procedure is to be called upon initialization when overridden.

The object i used as follows. Given Set is a handle to the training set to read, and Features_List is the list of features. The set can be effectively read as:

> `declare
> Transaction : Lecture_Update (Ptr (Set));
> begin
> Read
> ( File_Name => "training_set_file.txt",
> Lesson => Set,
> Features => Features_List
> );
> end;`

### 2.5. Classifiers

Classifier is an object used to classify samples of features into some set classes. The set of classes in which terms a classification is given can be viewed as a feature, so called class-feature. The process of creation and tuning a classifier is called training. The method of training determines the internal structure of the classifier. There can be many different methods of machine learning. The package Fuzzy.Classifier.Handle provides a general interface to the classifier objects of any kind.

#### 2.5.1. Handles to classifiers

The package Fuzzy.Classifier.Handle provides the type Classifier_Handle used to refer classifier objects:

> `type Classifier_Handle is tagged private;`

As objects classifiers can be created, modified and destroyed. The following operations are defined on Classifier_Handle:

> `function Classify
> ( Classifier : Classifier_Handle;
> Lesson : Lecture_Handle;
> Example : Positive;
> Generalize : Generalization_Mode := Linear;
> Threshold : Confidence := Confidence'First;
> Complement : Boolean := False
> ) return Classification;`

This functions uses the classifier specified by the handle Classifier to classify one example from a training set. The parameter Lesson is a handle to the training set. The example is specified by the parameter Example. Upon classification images not represented in the set are assumed unknown. The result of classification is an intuitionistic classification, a pair of fuzzy subsets of the domain set of the class- feature (see also Get_Classes). The first subset is the distribution of possibilities. It tells how possible is that the classified example belongs to the corresponding classes. The second tells how it is necessary. The parameter Complement, when true, indicates that the complement of the event behind the example has to be classified instead. So the result will be a classification of something opposite to the example. The parameter Generalize advises the classifier how to deal with the examples missing in the training set. It has the type Generalization_Mode, declared in the parent package Fuzzy.Classifier. The modes of generalization are:

- None for no generalization;
- Nearest for generalization to the nearest neighbor;
- Linear for interpolation of classifications between two neighbors.

The parameter Threshold specifies the truncation level. All confidence factors less than Threshold are treated as 0. Higher values of Threshold may speed up classification, though make it less precise. Constraint_Error is propagate when a handle or classifier s invalid.

Exceptions
Constraint_Error | An invalid handle
Data_Error | I/O error on training set

> `function Classify
> ( Classifier : Classifier_Handle;
> Context : not null access Classification_Parameters'Class;
> Complement : Boolean := False
> ) return Classification;`

When Classify has to be called for many examples of the same training set the it is preferable to create a classification_parameters once and reuse it in consequent calls to this variant of Classify.

> `function Estimate
> ( Classifier : Classifier_Handle;
> Lesson : Lecture_Handle;
> Example : Positive;
> Generalize : Generalization_Mode := Linear;
> Threshold : Confidence := Confidence'First;
> Complement : Boolean := False
> ) return Intuitionistic.Set;`

This function uses the classifier specified by the handle Classifier to estimate one example from a training set. The parameters are same as in Classify. The result is a proper intuitionistic fuzzy set, which estimates the example in terms of classes. I.e. it tells how possible and necessary is that the classes belong to the example, or else to its complement when the parameter Complement is true. Constraint_Error is propagate when a handle or classifier is invalid.

Exceptions
Constraint_Error | An invalid handle
Data_Error | I/O error on training set

> `function Estimate
> ( Classifier : Classifier_Handle;
> Context : not null access Classification_Parameters'Class;
> Complement : Boolean := False
> ) return Intuitionistic.Set;`

This variant of Estimate is used when it has to be called for many examples of the same training set with the same parameters. In this case the classification_parameters can be reused between the calls. The parameter Context specifies the classification_parameters.

> `function Get_Class (Classifier : Classifier_Handle) return String;`

The classifier class is known to the procedures dealing with the external persistent storage. When a classifier is archived, the way a it is converted to its canonical form in the persistent storage depends on the class. This function returns the classifier's class. It raises Constraint_Error if Classifier is invalid.

> `function Get_Classes (Classifier : Classifier_Handle)
> return Feature_Handle;`

Each classifier has a dedicated feature describing the set of classes. The result of a classification is a fuzzy set over the class- feature domain. This function returns the class- feature of Classifier. Constraint_Error is propagate when a handle or classifier is invalid.

> `procedure Get_Examples
> ( Classifier : Classifier_Handle;
> Lesson : in out Lecture_Handle;
> Viewer : Indicator_Handle
> );
> procedure Get_Examples
> ( Classifier : Classifier_Handle;
> Lesson : in out Lecture_Handle;
> Viewer : not null access Indicator_Object'Class := Negleter'Access
> );`

This procedure extracts training examples from the classifier specified by the handle Classifier. Each one should have a corresponding training set from which the classifier can be restored. The extracted examples are added to the training set specified by the handle Lesson. The parameter Viewer specifies an indication object. The progress of extracting is measured in percents. The parameter is either a pointer or a handle to the object. The handle can be invalid.

Exceptions
Constraint_Error | An invalid handle
Data_Error | I/O error when writing into the training set
End_Error | Operation was aborted by the indication object. Some examples have been added to the set, some not

> `function Get_Features (Classifier : Classifier_Handle)
> return Fuzzy.Feature.Handle.Container.Set;`

This function returns the set of features used by Classifier. This set contains the class-feature. Constraint_Error is propagated when Classifier is not a valid handle.

> `function Get_Training_Set_Name (Classifier : Classifier_Handle)
> return String;`

This function returns the name of the training set used to build the Classifier. The name is an UTF-8 encoded string that identifies the training set, usually in an external storage. The name may indicate no set or another set, and should be considered as a hint. The result is an empty string if no set name was set. Constraint_Error is propagated when Classifier is not a valid handle.

> `procedure Invalidate (Classifier : in out Classifier_Handle);`

This procedure detaches handle Classifier from the classifier object (if any) it points to. The result handle cannot be used to access any object. The referenced object is destroyed if it was the last handle.

> `function Is_Valid (Classifier : Classifier_Handle) return Boolean;`

This function checks whether a handle points to an object.

> `procedure Learn
> ( Classifier : in out Classifier_Handle;
> Lesson : Lecture_Handle;
> [ Name : String; ]
> Features : Feature_Array;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Threshold : Confidence := Confidence'First;
> Equivalence : Confidence := Default_Equivalence;
> Viewer : Indicator_Handle
> );
> procedure Learn
> ( ... -- parameters Classifier..Equivalence as above
> Viewer : access Indicator_Object'Class := Negleter'Access
> );`

This procedure modifies the classifier specified by the handle Classifier according to new training examples from the training set Lesson. It is used for incremental learning. Name is the external name (UTF-8 encoded) of the training set. When specified it can be queried from the classifier using Get_Training_Set_Name. The parameters From and To specify a range of examples used for training. Usually it is the whole set. The parameter To can be greater than the total number of examples. The parameter Features specifies the sequence of features. The list may contain invalid (No_Feature) elements, which are ignored. The sequence may be empty. The parameter Threshold specifies the truncation level. All confidence factors below Threshold are treated as 0. The parameter Equivalence is the level of separation hypotheses quality. If the qualities differ less than Equivalence, they are assumed same. When Equivalence is Confidence'Last, features are not selected, so they order of testing is not changed, unless some features are undefined. The parameter Viewer specifies an indication object. The progress of training is measured in percents. This parameter is either a pointer or a handle to the indication object. In the latter case the handle can be invalid.

Exceptions
Constraint_Error | An invalid handle
Data_Error | I/O error when writing into the training set
End_Error | Operation was aborted by the indication object. Some examples have been used in learning, some not
Use_Error | One of the features specified depends on the classifier. Circular dependencies are not allowed. This exception may also indicate that the classified does not support incremental learning.

> `procedure Learn
> ( Classifier : in out Classifier_Handle;
> Context : in out Training_Data'Class;
> Features : Feature_Array;
> From : Positive := 1;
> To : Positive := Positive'Last;
> );`

This procedure is a variant of Learn with the parameter Context specifying the training data. The parameters From and To specify a range of examples used for training. The parameter Features specifies the sequence of features. Constraint_Error is propagated when Context cannot be used for training Classifier.

> `function Ptr (Classifier : Classifier_Handle) return Classifier_Object_Ptr;`

This function is used to get a pointer to the classifier object a handle points to. Constraint_Error is propagated if the handle is invalid. The pointer of to the object shall be used no longer the handle it was get from exists.

> `function Ref (Classifier : Classifier_Object_Ptr)
> return Classifier_Handle;`

This function is used to get a handle from a pointer to a classifier object.

> `procedure Ref
> ( Handle : in out Classifier_Handle;
> Classifier : Classifier_Object_Ptr
> );`

This procedure assigns a classifier object to handle.

> `function To_Classifier_Handle
> ( Classifier : Deposit_Handles.Handle
> ) return Classifier_Handle;`

This function provides a backward handle conversion from a general persistent object handle to Classifier_Handle. Constraint_Error is propagated when Classifier is not a valid handle or does not refer a classifier object.

> `function To_Deposit_Handle (Classifier : Classifier_Handle)
> return Deposit_Handles.Handle;`

This function provides handle conversion from Classifier_Handle to a general persistent object handle. Constraint_Error is propagated when Classifier is not a valid handle.

> `procedure Verify
> ( Classifier : Classifier_Handle;
> Lesson : Lecture_Handle;
> Result : in out Lecture_Handle;
> Report : in out Fuzzy.Intuitionistic.Set;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Generalize : Generalization_Mode := Linear;
> Threshold : Confidence := Confidence'First;
> Viewer : Indicator_Handle;
> Difference : Divergence_Function := Diff'Access
> );
> procedure Verify
> ( ... -- parameters Classifier..Threshold as above
> Viewer : not null access Indicator_Object'Class := Negleter'Access;
> Difference : Divergence_Function := Diff'Access
> );`

These procedures are used to validate a classifier against examples from a fuzzy training set (the parameter Lesson). The classifier is specified by the handle Classifier. The procedures process the examples From..To of the set. The parameter To may be greater than the total number of the examples in the training set. Images not represented in the set are assumed unknown. The parameters Generalize and Threshold are same as in Classify. The classifications of the images of the selected examples are compared with the corresponding images of the class- feature in the example using the function Divergence, which estimates the difference between logical values. The result of comparison is stored into the training set Result as a value of the class- feature. The mean of the differences is returned for each class into the parameter Report. The set of classes is the domain set of the class- feature (see Get_Classes). So the result is an intuitionistic set, which for each class tells how possible and necessary (the means of) is that the classifier misclassifies an example. The necessity-possibility pair here defines the interval, where the misclassification rate might be. The parameter Viewer specifies an indication object. The progress of extracting is measured in percents. It can be either a pointer to an object or a handle to. The handle can be invalid in which case no indication is made.When Result is an invalid handle an new memory-resident training set is created as necessary.

Exceptions
Constraint_Error | An invalid handle, wrong cardinality of Report
Data_Error | I/O error when writing into the training set
End_Error | Operation was aborted by the indication object.

> `function Verify
> ( Classifier : Classifier_Handle;
> Lesson : Lecture_Handle;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Generalize : Generalization_Mode := Linear;
> Threshold : Confidence := Confidence'First;
> Viewer : Indicator_Handle;
> Difference : Divergence_Function := Diff'Access
> ) return Fuzzy.Intuitionistic.Set;
> function Verify
> ( ... -- parameters Classifier..Threshold as above
> Viewer : Indicator_Handle := No_Indicator;
> Difference : Divergence_Function := Diff'Access
> ) return Fuzzy.Intuitionistic.Set;`

This function is a simplified version the procedures Verify with no Result parameter and Report returned as the result.

Exceptions
Constraint_Error | An invalid handle
Data_Error | I/O error when writing into the training set
End_Error | Operation was aborted by the indication object.

> `procedure Verify
> ( Classifier : Classifier_Handle;
> Context : in out Classification_Parameters'Class;
> Result : in out Lecture_Handle;
> Report : in out Fuzzy.Intuitionistic.Set;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Difference : Divergence_Function := Diff'Access
> );
> function Verify
> ( Classifier : Classifier_Handle;
> Context : access Classification_Parameters'Class;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Difference : Divergence_Function := Diff'Access
> ) return Fuzzy.Intuitionistic.Set;`

These two subprograms are variants of the procedure Verify and the function Verify with the parameter Context defining the classification_parameters.

#### 2.5.2. Creating classifier

The package Fuzzy.Classifier.Handle.Factory provides tools for creating new classifiers.

> `function Identity (Classes : Feature_Handle)
> return Classifier_Handle;`

This function creates a trivial identity classifier. The classifier simply repeats the value of the feature Classes from the training set example being classified. Identity classifiers can be considered as a way to convert a feature to a classifier. The backward conversion is achieved through classificatory features. Constraint_Error is propagated when Classes is not a valid handle.

> `function Learn
> ( Lesson : Lecture_Handle;
> [ Name : String; ]
> Features : Feature_Array;
> Classes : Feature_Handle;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Threshold : Confidence := Confidence'First;
> Equivalence : Confidence := Default_Equivalence;
> Viewer : Indicator_Handle;
> Factory : not null access Fuzzy.Graph.Node_Factory'Class :=
> Fuzzy.Graph.Memory_Resident.Factory
> ) return Classifier_Handle;
> function Learn
> ( ... -- parameters Lesson..Equivalence as above
> Viewer : not null access Indicator_Object'Class :=
> Negleter'Access;
> Factory : not null access Fuzzy.Graph.Node_Factory'Class :=
> Fuzzy.Graph.Memory_Resident.Factory
> ) return Classifier_Handle;`

These two functions build a graph-scheme from the fuzzy training set Lesson. Name is the external name (UTF-8 encoded) of the training set. When specified it can be queried from the classifier using Get_Training_Set_Name. The parameters From and To specify the range of examples used for learning. Usually it is the whole set. The parameter To can be greater than the total number of examples. The parameter Features specifies the sequence of features. It has the type Feature_Array defined in the package Fuzzy.Feature.Handle. The nodes of the graph-scheme will test the features in the order specified by the sequence. The order has a substantial influence on the resulting graph. The list may contain No_Feature elements, which are ignored. The parameter Classes is a handle to the class-feature describing the set of classes the graph should classify to. It must be a valid handle and a feature different from any from Features. The parameter Threshold specifies the truncation level. All confidence factors below Threshold are treated as 0. This can speed-up training and prune the resulting graph-scheme. The parameter Equivalence is the level of separation hypotheses quality. If the qualities differ less than Equivalence, they are assumed same. When Equivalence is Confidence'Last, features are not selected, so they order of testing is not changed, unless some features are undefined. The parameter Viewer specifies an indication object. The graph-scheme construction progress is indicated in percents. It can be aborted by Viewer. The parameter Viewer can be either a pointer or a handle to the indicator object. In the latter case the handle can be invalid. The parameter Factory specifies the node factory used by default to create new nodes. Usually it is the first node created. The node factory can used for generating special nodes. By default the standard node factory is used that creates nodes in the memory.

Exceptions
Constraint_Error | An invalid handle
Data_Error | I/O error while reading the training set
End_Error | Operation was aborted by the indication object

> `function Learn
> ( Context : access Training_Data'Class;
> Features : Feature_Array;
> From : Positive := 1;
> To : Positive := Positive'Last;
> ) return Classifier_Handle;`

This variant of Learn creates a classifier using the training data specified by the parameter Context. The type of the classifier is determined by Context. Constraint_Error may propagate when Context is not supported.

> `function Separator
> ( Classifier : Classifier_Handle;
> Separation : Confidence := Confidence'First;
> Completeness : Confidence := Confidence'Last
> ) return Classifier_Handle;`

This function creates a classifier that separates classes. It is built upon another classifier specified by the parameter Classifier. A separator classifier uses Classifier to classify classes known to be separate and complete to the levels specified to the parameters Separation and Completeness. Let C={cj | cj:Ω→[0,1]} be the set of fuzzy classes such that P(∩cj)≤a and N(∪cj)≥b. The parameter Separation is the confidence level of class separation. That is the possibility a of the intersection of the classes or else its estimation from above. The parameter Completeness is the confidence level of class completeness, i.e. the necessity b of the class union or its estimation from below. The built classifier uses the knowledge about the classes to refine the classifications given by the original classifier. Constraint_Error is propagated if Classifier is not a valid handle.

#### 2.5.3. Output in HTML format

The package Fuzzy.Classifier.Handle.HTML provides output of graph-schemes in the HTML format. The package provides two variants of the output subprograms. One is used for an arbitrary file, another is for the standard output file:

> `procedure Put
> ( File : File_Type;
> Classifier : Classifier_Handle;
> Parameters : HTML_Parameters'Class := HTML_Defaults
> );`

or for the standard output:

> `procedure Put
> ( Classifier : Classifier_Handle;
> Parameters : HTML_Parameters'Class := HTML_Defaults
> );`

These procedures write Classifier into a file in the HTML format. The output has a form of a table. It is controlled by the fields of Parameters as described in Fuzzy.Feature.Handle. HTML. Constraint_Error is raised when Node is an invalid handle or a wrong node. I/O exceptions may propagate if file output fails. Constraint_Error is propagated when Classifier is an invalid handle or a wrong node. I/O exceptions may propagate if file output fails.

See also the example 3 for an instance of graph-scheme HTML output.

### 2.6. Graphs

Graphs and graph-schemes are used as the knowledge carrier. A graph consists of node objects. The nodes are subordinated by parent-child relationship. There are three sorts of nodes. Root nodes may have no parents. Branch nodes may have both parents and children. Leaf nodes may have no children. Each node tests some feature. Any node can be viewed as a graph rooted in the node. This graph consists of the node and all its descendants. A graph can be used for training and classification. Graphs created from different images comprise a graph-scheme which can also act as a classifier combining the knowledge obtained from all available images. Basically a graph-scheme consists of four fuzzy graphs one per image type.

#### 2.6.1. Handles to nodes

The package Fuzzy.Graph.Handle provides the type Node_Handle to access graph node objects. The graph nodes when modified through handles are replicated as necessary to provide consistent view through other handles. For example, if a node is changed through one handle and is viewed through another, then the latter will see no changes in its view. Therefore there is no need to explicitly copy graph nodes. It will be made automatically when necessary. Further, the implementation of the graph nodes supports node re-use where possible. Thus if the result of an operation is equivalent to some existing node, that node will be the result.

The following operations are defined on Node_Handle:

> `function Classify
> ( Node : Node_Handle;
> Lesson : Lecture_Handle;
> Example : Positive;
> Image : Image_Type;
> Generalize : Generalization_Mode := Linear;
> Threshold : Confidence := Confidence'First
> ) return Classification;`

This function uses the graph rooted in Node to classify one example from a fuzzy training set. The graph rooted in a node may act as a classifier. The parameter Lesson is a handle to. The function classifies only one example from the training set. The example is specified by the parameter Example. Images not represented in the training set are assumed unknown. The result of classification is a pair of distributions of confidence factors over the classes. It is an intuitionistic classification. The set of classes is the domain set of the class-feature (see also Get_Classes). The parameter Image specifies the image to classify. The parameter Generalize advises the classifier how to deal with the examples missing in the training set. It has the type Generalization_Mode, declared in the parent package Fuzzy.Classifier. The parameter Threshold specifies the truncation level. All confidence factors below Threshold are treated as 0. Higher values of Threshold may speed up classification, though make it less precise. The parameter Node can be an invalid handle in which case the result of classification is uncertain. Contraint_Error is propagated when Node refers a wrong node. Data_Error is propagated on I/O errors in the training set.

> `function Classify
> ( Node : Node_Handle;
> Context : not null access Classification_Parameters'Class;
> Image : Image_Type;
> ) return Classification;`

This variant of Classifiy is preferable if several consequent classifications has to be performed using the same training set. Its parameter Context is a classification_parameters that can be reused between the calls.

> `function Find
> ( Parent : Node_Handle;
> Child : Node_Handle;
> Index : Positive
> ) return Natural;`

This function searches for a child node. If the node Child is a direct successor of Parent, then the result is the index of a domain set value for which Parent has an arc leading to Child. The function starts search from the domain value Index. The result is zero if the search fails, for example when the handle Parent is invalid or refers a leaf node. It is also zero when Child is invalid.

> `function Find
> ( Node : Node_Handle;
> Feature : Feature_Handle
> ) return Node_Handle;`

This function searches for any node testing Feature that belongs to the same graph as Node. The result is a handle to the node. It is an invalid handle if there is no one or if Feature is an invalid handle. Constraint_Error is propagated when Node is an invalid handle.

> `function Get_Cardinality (Node : Node_Handle)
> return Positive;`

The cardinality of a node is the cardinality of the feature it tests. A leaf node also tests a feature, which is the class-feature. Constraint_Error is propagated when Node is invalid.

> `function Get_Child
> ( Node : Node_Handle;
> Index : Positive
> ) return Node_Handle;`

This function returns handle to a child node. The number of children may vary from 0 to the node cardinality. The parameter Index is the index of the feature domain value. Observe that the same child node can be associated with several domain values. The result is a handle to the child node or an invalid handle when there is no child node corresponding to Index (also when Index is greater than the node cardinality.) Constraint_Error is propagated when the handle Node is invalid. See also Get_Children.

> `function Get_Children_Number
> ( Node : Node_Handle;
> Immediate : Boolean := True
> ) return Natural;`

This function returns the number of successors of the node Node. Only immediate successors are counted when Immediate is true. Zero is returned if Node is an invalid handle. Note that Get_Children_Number treats Node as a root node of a tree. It means that if the same child node is a accessible through several different paths from Node it will be counted as many times. So the number of distinct nodes could be far lesser than the value returned by Get_Children_Number.

> `function Get_Class (Node : Node_Handle) return String;`

The node class is known to the procedures dealing with the external persistent storage. When a node is archived, the way a it is converted to its canonical form in the persistent storage depends on the class. This function returns the node class. It raises Constraint_Error if Lesson is invalid.

> `function Get_Classes (Node : Node_Handle)
> return Feature_Handle;`

This function returns a handle to the class-feature. Each graph has a dedicated feature describing the set of classes. The result of a classification by the graph rooted in Node is a classification of the class-feature. Constraint_Error is propagated when Node is an invalid handle or refers an invalid node that belongs to no graph.

> `function Get_Distribution (Node : Node_Handle)
> return Classification;`

The result is a classification of the feature tested by the node. For a leaf node it is an ultimate classification given by the leaf under the condition that the leaf was reached. For other nodes it is the weights of the arcs leading out of the node, i.e. a conditional classification. Constraint_Error is propagated when Node is an invalid handle or refers a node of no graph.

> `procedure Get_Examples
> ( Node : Node_Handle;
> Lesson : in out Lecture_Handle;
> Image : Image_Type;
> Viewer : Indicator_Handle
> );
> procedure Get_Examples
> ( Node : Node_Handle;
> Lesson : in out Lecture_Handle;
> Image : Image_Type;
> Viewer : access Indicator_Object'Class := Negleter'Access
> );`

This procedure extracts training examples from the graph rooted in Node. Each graph has a corresponding training set which exhaustively describes it. The extracted examples are added to the training set specified by the handle Lesson. The parameter Image determines which feature images have to be defined by the extracted examples. Though it has no effect on the class-feature, of which classifications (has-in, has-not images) are defined. The parameter Viewer specifies an indication object. The progress of is measured in percent. The parameter is either a pointer or a handle to the indication object. The handle can be invalid.

Exceptions
Constraint_Error | An invalid handle
Data_Error | I/O error when writing into the training set
End_Error | Operation was aborted by the indication object. Some extracted examples are added to Lesson, some are not.

> `function Get_Feature (Node : Node_Handle)
> return Feature_Handle;`

This function returns a handle to the feature the node tests. Constraint_Error is propagated if Node is an invalid handle or a node that belongs to no graph.

> `function Get_Type (Node : Node_Handle) return Node_Type;`

This function returns the node type which is either Tree_Branch or Tree_Leaf. Root nodes are branches with no parents. The type Node_Type is declared in the package Fuzzy.Graph. Leaf nodes have no children. Constraint_Error is propagated if Node is an invalid handle.

> `procedure Invalidate (Node : in out Node_Handle);`

This procedure detaches handle from the object (if any) it points to. The result handle cannot be used to access the node. The referenced node is destroyed if that was the last handle.

> `function Is_Valid (Node : Node_Handle) return Boolean;`

This function checks whether a handle points to a node.

> `function Ptr (Node : Node_Handle) return Graph_Node_Ptr;`

This function returns a pointer to the node object pointed by the handle Node. Constraint_Error is propagated if the handle is invalid. The pointer of to the object shall be used no longer the handle it was get from exists.

> `function Ref (Node : Graph_Node_Ptr)
> return Node_Handle;`

This function is used to get a handle from a pointer to the node object.

> `procedure Ref
> ( Handle : in out Node_Handle;
> Node : Graph_Node_Ptr
> );`

This procedure assigns a node object to handle.

> `function Tests
> ( Node : Node_Handle;
> Feature : Feature_Handle
> ) return Boolean;`

This function returns true if at least one of the nodes of the graph rooted in Node tests the feature indicated by the handle Feature. Constraint_Error is propagated if Node is an invalid handle.

> `function To_Deposit_Handle (Node : Node_Handle)
> return Deposit_Handles.Handle;`

This function provides handle conversion from Node_Handle to a general persistent object handle. Constraint_Error is propagated when Node is not a valid handle.

> `function To_Node_Handle
> ( Node : Deposit_Handles.Handle
> ) return Node_Handle;`

This function provides a backward handle conversion from a general persistent object handle to Node_Handle. Constraint_Error is propagated when Node is not a valid handle or does not refer a node object.

> `function "<" (Left, Right : Node_Handle) return Boolean;
> function "<="(Left, Right : Node_Handle) return Boolean;
> function ">="(Left, Right : Node_Handle) return Boolean;
> function ">" (Left, Right : Node_Handle) return Boolean;
> function "=" (Left, Right : Node_Handle) return Boolean;`

Valid node handles are comparable. If one of arguments is invalid Contraint_Error is propagated for all functions except "=". For equality (and thus inequality) it is legal to compare with an invalid handle. The result of such comparison is true if and only if both handles are invalid. One of parameters in equality is allowed to be a pointer to an object.

The package also defines:

> `type Node_Array is array (Integer range <>) of Node_Handle;`

The array of node handles.

> `No_Node : constant Node_Handle;`

No_Node is an invalid handle.

> `function Get_Number_Of_Nodes return Natural;`

This function returns the total number of node objects.

#### 2.6.2. Node containers

Sets | The package Fuzzy.Graph.Handle.Container defines the type Set which representing a set of node handles. It has the same interface as the package Object.Handle.Generic_Set. It defines the type Set which representing a set of node handles.
Bounded arrays | The package Fuzzy.Graph.Handle.Bounded_Arrays provides bounded arrays of features. Basically it is an instantiation of the package Generic_Bounded_Array. It has exactly the same interface. Though for implementation reasons it a proxy rather than being an immediate instantiation.
Plain arrays | The type Node_Array defined in the package Fuzzy.Graph.Handle.

#### 2.6.3. Operations on graphs

The package Fuzzy.Graph.Handle.Layer provides operations on graphs that potentially involve more than one node or modify the graph:

> `procedure Connect
> ( Parent : in out Node_Handle;
> Child : Node_Handle;
> Index : Positive;
> Data : in out Node_Modification_Data'Class
> );
> procedure Connect
> ( Parent : in out Node_Handle;
> Child : Node_Handle;
> Index : Positive
> );`

This procedure connects the node specified by the handle Child to the node Parent. As the result of the parent node will have arc Parent->Child connected to the point Index. It is the index of the domain set value of the feature tested by Parent for which Child is the successor. A child node can be connected to same parent at more than one point. Both Parent and Child shall belong to a graph and it must be the same graph, otherwise Constraint_Error is propagated. Constraint_Error is also propagated when either Parent or Child is invalid handle or Parent is not a branch node. The connected node cannot be an ancestor of Parent. Otherwise, Use_error is propagated. Note also that if Connect changes Parent, then these changes are local to the handle Parent. All other users of the modified node will continue to observe the old node. In particular the Parent's parent. It means that Parent have to be re-connected to its parent to make the latter aware of the changes made. The parameter Data specifies the node modification context to use. It can be omitted, in which case it is generated as necessary.

> `function Get_Children (Node : Node_Handle)
> return Node_Set;`

This function returns the set of handles of all immediate children of the node. For a leaf node the result is an empty set. An empty set is also returned when Node is an invalid handle.

> `function Get_Elder_Feature (Node : Node_Handle)
> return Feature_Handle;`

This function returns the elder feature tested by non-leaf children of the node. For two nodes A and B the feature tested by A is elder than one of B if B is a descendant of A. The function tries to find the most elder feature tested by non-leaf nodes descending from the Node. No_Feature is returned if there are only leaf nodes. Constraint_Error is propagated when Node is not a valid handle.

> `function Get_Feature (Node : Node_Handle; Index : Positive)
> return Feature_Handle;`

All features of tested by nodes of a graph are enumerated from 1. They can be queried using this function. The parameter Node can specify any node of the graph. The parameter Index should be in the range 1..Get_Features_Number (Node). Constraint_Error is propagated when Node is not a valid handle or Index is out of the range.

> `function Get_Features (Node : Node_Handle)
> return Fuzzy.Feature.Handle.Container.Set;`

This function returns the set of all features tested by the graph of Node. The result can be an empty set, when Node refers to a wrong node which belongs to no graph. Otherwise the result contains the class-feature. Constraint_Error is propagated if Node is an invalid handle.

> `function Get_Features_Number (Node : Node_Handle) return Natural;`

The number of the features tested by the graph containing Node. It includes the class-feature. The result is 0, when Node is not a valid handle.

> `function Get_Layer
> ( Node : Node_Handle;
> Feature : Feature_Handle
> ) return Fuzzy.Graph.Handle.Container.Set;`

This function returns the set of all graph nodes testing Feature. The graph can be identified by any of its nodes (the parameter Node). The result can be empty if Feature is not a valid handle, not tested by the graph, or Node does not belong to any graph. Constraint_Error is propagated if Node is an invalid handle.

> `function Get_Layer_Size
> ( Node : Node_Handle;
> Feature : Feature_Handle
> ) return Natural;`

This function returns the number of the graph nodes testing the feature pointed by the handle Feature. The graph can be identified by any of its nodes. Zero is returned if Feature is invalid, not tested by the graph or Node does not belong to any graph. Constraint_Error is propagated if Node is an invalid handle.

> `function Get_Parents (Node : Node_Handle)
> return Fuzzy.Graph.Handle.Container.Set;`

This function returns a set of all immediate ancestors of the node. For a root node the result is an empty set. An empty set is also returned when the node handle is invalid or wrong (not in a graph).

> `function Get_Sibling (Node : Node_Handle; Index : Positive)
> return Node_Handle;`

This function allows enumeration of a graph layer. A layer consists of the nodes testing the same feature. The parameter Node identifies one node of the layer. The parameter Index indicates the number of a node in the layer. All nodes of a layer are enumerated from 1 to Get_Siblings_Number. The result is a handle to the node testing the same feature as Node, it can be the same node. Contraint_Error is propagated when Node is an invalid handle, refers a wrong node or there is no sibling for Index.

> `function Get_Siblings_Number (Node : Node_Handle)
> return Natural;`

This function returns the number of nodes in a graph layer. A layer consists of the nodes testing the same feature. The parameter Node identifies one node of the layer. Zero is returned when Node is not a valid handle or refers a wrong node.

> `function Get_Size (Node : Node_Handle) return Positive;`

This function returns the number of distinct nodes in the graph the node belongs to. Constraint_Error is propagated if Node is an invalid handle or wrong.

> `procedure Replace
> ( Parent : in out Node_Handle;
> Old_Child : Node_Handle;
> New_Child : Node_Handle;
> Data : in out Node_Modification_Data'Class
> );
> procedure Replace
> ( Parent : in out Node_Handle;
> Old_Child : Node_Handle;
> New_Child : Node_Handle
> );`

This procedure replaces all arcs from Parent to Old_Child with ones leading to New_Child. Nothing happens if Old_Child and New_Child are same or Old_Child is not a child node of Parent. Both Parent and New_Child shall belong to a graph and it must be the same graph, otherwise Constraint_Error is propagated. It is also propagated when Parent is an invalid handle or then node is not a branch node. New_Child and Old_Child can be invalid handles, which can be used for removing arcs and adding new ones. When New_Child is valid it cannot be an ancestor of Parent. Otherwise Use_Error is propagated. When New_Child is invalid, then Replace might invalidate Parent if the last arc leading out of it was removed. The parameter Data specifies the node modification context to use. It can be omitted, in which case it is generated as necessary.

> `procedure Sew (Node : in out Node_Handle);`

This procedure removes the specified node from the graph it belongs to. When the node has a parent, then all arcs from the parent to the node are removed. All successors of the removed node are removed as well if they have no other parents. All parents of the removed node are also removed if the node was their last descendant. The handle Node is invalidated by the procedure. Nothing happens if Node is already not a valid handle.

#### 2.6.4. Manual creation of graphs

The package Fuzzy.Graph.Handle.Manual provides subroutines to create a graph-scheme node by node. It is rarely used because a normal way of creating graph-schemes is by training. Though, see example 2 which illustrates use of Fuzzy.Graph.Handle.Manual.

> `function Create_Branch
> ( Feature : Feature_Handle;
> Children : Node_Array
> ) return Node_Handle;
> function Create_Branch
> ( Feature : Feature_Handle;
> Children : Bounded_Array;
> ) return Node_Handle;`

These procedures create a branch node. The node will test the feature specified by the parameter Feature. The children nodes are specified by the parameter Children. It can be either a plain array or a bounded array of handles. For each valid node handle of the array Children the branch node will have an arc leading to this node. The array Children shall have the length equal to the cardinality of Feature. Children may contain invalid handles to indicate unspecified domain values. But at least one handle have to be valid. All children nodes shall belong to the same graph which will be the graph of the branch. Constraint_Error is propagated when Feature is invalid, there is no valid node in Children, some of children are of different or no graph.

> `function Create_Leaf
> ( Feature : Feature_Handle;
> Distribution : Classification;
> Factory : access Node_Factory'Class :=
> Fuzzy.Graph.Memory_Resident.Factory
> ) return Node_Handle;
> function Create_Leaf
> ( Feature : Feature_Handle;
> Distribution : Classification;
> Node : Node_Handle
> ) return Node_Handle;`

These function create a leaf (terminal) node. The parameter Feature is the class-feature of which Distribution is the classification provided by the node. The cardinality of the feature has to be same as one of the classification given by the leaf. The parameter Factory is the node factory. By default it is a factory of memory-resident nodes. Alternatively one can specify any node of the graph where the leaf should be created.

#### 2.6.5. Learning

The package Fuzzy.Graph.Handle.Learning provides subroutines for learning graphs from training sets. Learning is a process of building or modifying a graph. It is recommended to train graph-schemes instead of doing that directly on graphs. To learn one needs a training set and a list of features the graph will use. The following subprograms are provided by the package:

> `function Learn
> ( Lesson : Lecture_Handle;
> Features : Feature_Array;
> Classes : Feature_Handle;
> Image : Image_Type;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Threshold : Confidence := Confidence'First;
> Equivalence : Confidence := Default_Equivalence;
> Viewer : Indicator_Handle;
> Factory : access Node_Factory'Class :=
> Fuzzy.Graph.Memory_Resident.Factory
> ) return Node_Handle;
> function Learn
> ( ... -- parameters Lesson..Equivalence as above
> Viewer : access Indicator_Object'Class := Negleter'Access;
> Factory : access Node_Factory'Class :=
> Fuzzy.Graph.Memory_Resident.Factory
> ) return Node_Handle;`

These functions build a graph from the fuzzy training set Lesson. The parameters From, To specify the range of training examples used for learning. Usually it is the whole set. The parameter To can be greater than the total number of examples. The parameter Image indicates the image type to learn from. The parameter Features specifies the sequence of features. The nodes of the graph will test the features in the order specified by the sequence. The order has a substantial influence on the resulting graph. The list may contain No_Feature elements, which are ignored. The parameter Classes is a feature describing the set of classes the graph should classify to. The parameter Threshold specifies the truncation level. All confidence factors below Threshold are treated as 0. The parameter Equivalence is the level of separation hypotheses quality. If the qualities differ less than Equivalence, they are assumed same. When Equivalence is Confidence'Last, features are not selected, so they order of testing is not changed, unless some features are undefined. The parameter Viewer specifies an indication object. The progress of extracting is measured in percents. The parameter is either a pointer or a handle to the indication object. The handle can be invalid. The parameter Factory specifies the node factory used by default to create new nodes. Usually it is the first node created. The result or training might be an empty graph in which case an invalid handle is returned.

Exceptions
Constraint_Error | An invalid handle
Data_Error | I/O error in the training set
End_Error | Operation was aborted by the indication object.

> `procedure Learn
> ( Node : in out Node_Handle;
> Lesson : Lecture_Handle;
> Features : Feature_Array;
> Image : Image_Type;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Threshold : Confidence := Confidence'First;
> Viewer : Indicator_Handle
> );
> procedure Learn
> ( ... -- parameters Node..Threshold as above
> Viewer : access Indicator_Object'Class := Negleter'Access
> );`

These procedures modify a graph according to new training examples from the training set Lesson. The parameter Node is a node of the graph. It can be any node of it, but usually it is the root node. So the procedures can be used for incremental learning. Though it is always recommended to use Fuzzy.Classifier.Handle.Learn (with a graph-scheme) instead. The parameters From, To specify the range of training examples used for learning. Usually it is the whole set. The parameter To can be greater than the total number of examples. The parameter Image specifies the image to learn from. The parameter Features specifies the sequence of features. The list may contain No_Feature elements, which are ignored. The sequence may be empty. The parameter Threshold specifies the truncation level. All confidence factors below Threshold are treated as 0. The parameter Viewer specifies an indication object. The progress of extracting is measured in percents. The parameter is either a pointer or a handle to the indication object. The handle can be invalid. Note that not all images are compatible in incremental learning. It is only possible to mix has-in with has-out and has-not with has-not-out. In each pair is reasonable to start learning with the first image and attune the result with learning on the second image.

Exceptions
Constraint_Error | An invalid handle
Data_Error | I/O error in the training set
End_Error | Operation was aborted by the indication object.
Use_Error | One of the features specified depends on the classifier. Circular dependencies are not allowed. This exception may also indicate that the classified does not support incremental learning.

> `procedure Learn
> ( Node : in out Node_Handle;
> Context : in out Graph_Training_Data'Class;
> Image : Image_Type;
> );`

This procedure modifies a graph according to new training examples from the training set associated with the graph training data Context. The parameter Node is a handle to a node of the graph. It can be any node of it, but usually it is the root node. When Node is an invalid handle it is trained anew. The parameter Image specifies the image to learn from.

Exceptions
Constraint_Error | An invalid graph node
Data_Error | I/O error in the training set
End_Error | Operation was aborted by the indication object.
Use_Error | One of the features specified depends on the classifier. Circular dependencies are not allowed. This exception may also indicate that the classified does not support incremental learning.

#### 2.6.6. String edit

The package Fuzzy.Graph.Handle.Edit provides simple string I/O facilities for graphs. The graphs rooted in a node can be get from and put into a string. The following subroutines are provided by the package:

> `procedure Get
> ( Source : String;
> Pointer : in out Integer;
> Node : out Node_Handle;
> Features : Table;
> Parameters : Input_Parameters'Class := Input_Defaults;
> Factory : access Node_Factory'Class :=
> Fuzzy.Graph.Memory_Resident.Factory
> );`

This procedure gets a graph from the text string Source. It starts in Source (Pointer) and advances Pointer to the first string position following the graph image. The syntax of a graph is as follows:

> `<graph>` | `::=` | `<branch> | <leaf>`
> `<leaf>` | `::=` | `<feature> = <classification>`
> `<branch>` | `::=` | `<feature> ( <children> )`
> `<children>` | `::=` | `<child> [; <children>]`
> `<child>` | `::=` | `<condition> => <graph>`
> `<condition>` | `::=` | `<interval> [, <condition>]`

Here `<feature>` is a feature name. The names of all features to expect are provided by the table Features. This parameter is a table which maps unique feature names to handles. `<classification>` is a classification of the feature as described in Fuzzy.Feature.Handle.Edit. Its syntax depends on the actual feature specified before (see `<leaf>`). `<interval>` is an interval of the feature domain set values (Fuzzy.Feature.Handle.Edit). Its syntax also depends on the feature (see `<branch>`). Singular values are valid. The input of feature values is controlled by the fields of Parameters. Additional constraint imposed is that all leaf nodes have same feature. Also the conditions specified for one branch may not overlap. Spaces and tabulators may surround the delimiters colored red: "`=`", "`(`", "`)`", "`;`", "`=>`", "`,`". The graph nodes are created using the node factory provided by the parameter Factory. The result is returned as a handle to the root node of created graph. The following example represents the graph created manually in the example 2. It can be input from the string:

> `Covering ( Feather => Limbs ( Legs..Wings => Creature = Bird ); Fur => Limbs ( Legs..Wings => Creature = Beast; Fins => Creature = Seal ); Scale => Limbs ( Legs => Creature = Reptile; Fins => Creature = Fish ); None => Limbs ( Legs => Creature = Human ) )`

Exceptions
Data_Error | Syntax error, violated constraint on data
End_Error | Nothing is recognized
Layout_Error | Pointer is not in the range Source'First..Source'Last+1
Use_Error | An invalid handle in Features

> `function Value
> ( Source : String;
> Features : Table;
> Parameters : Input_Parameters'Class := Input_Defaults;
> Factory : access Node_Factory'Class :=
> Fuzzy.Graph.Memory_Resident.Factory
> ) return Node_Handle;`

This function is a simplified version of the procedure Get. It parses the string Source and returns the corresponding graph. The whole string have to be matched. Otherwise, Data_Error is propagated.

Exceptions
Data_Error | Syntax error, violated constraint on data, Source is not fully matched
End_Error | Nothing is recognized
Use_Error | An invalid handle in Features

> `procedure Put
> ( Destination : in out String;
> Pointer : in out Integer;
> Node : Node_Handle;
> Parameters : Output_Parameters'Class := Output_Defaults;
> Field : Natural := 0;
> Justify : Alignment := Left;
> Fill : Character := ' '
> );`

This procedure outputs the graph rooted in Node into the string Destination. The string is written starting from the Destination (Pointer). Pointer is advanced to point to the first character following the output. The output is controlled by the field of Parameters. The parameter Field determines the width of the output field. Zero width means the minimal possible width. If Field is not zero Justify determines the way the value should be aligned within the output field. The parameter Fill is then the fill character. The syntax of output is described for the procedure Get.

Exceptions
Constraint_Error | Invalid handle Node, the node pointed by Node belongs to no graph
Layout_Error | The value of Pointer is not in the range Destination'Range or there is no room for the output

> `function Image
> ( Node : Node_Handle;
> Parameters : Output_Parameters'Class := Output_Defaults
> ) return String;`

These functions convert the graph rooted in Node to string. They are simplified versions of corresponding Put.

Exceptions
Constraint_Error | Invalid handle Node, the node pointed by Node belongs to no graph

#### 2.6.7. Output in HTML format

The package Fuzzy.Graph.Handle.HTML provides output of graphs in the HTML format. The package has two variants of the output subprograms. One is used for an arbitrary file, another is for the standard output file:

> `procedure Put
> ( File : File_Type;
> Node : Node_Handle;
> Parameters : HTML_Parameters'Class := HTML_Defaults
> );`

or for the standard output:

> `procedure Put
> ( Node : Node_Handle;
> Parameters : HTML_Parameters'Class := HTML_Defaults
> );`

These procedures write the graph rooted in the node indicated by the handle Node into a file in the HTML format. The output has a form of a table. It is controlled by the fields of Parameters as described in Fuzzy.Feature.Handle.HTML. Constraint_Error is raised when Node is an invalid handle or a wrong node. I/O exceptions may propagate if file output fails.

See also the example 2 for an instance of graph-scheme HTML output.

#### 2.6.8. Graph transformations

The package Fuzzy.Graph.Handle.Transformations provides some higher-level operations of graphs. It provides the following subroutines:

> `procedure Rotate
> ( Node : in out Node_Handle;
> Feature : Feature_Handle
> );
> procedure Rotate
> ( Node : in out Node_Handle;
> Feature : Feature_Handle;
> Data : in out Node_Modification_Data'Class
> );`

These procedures rotate the graph rooted in Node (a handle to) around Feature (a handle to). The result is returned through Node. The rotated graph is defined as an equivalent graph with the root node testing Feature. When the graph rooted in Node does not test Feature, it is not changed. The newly nodes are created using the factory and the setting specified by the node modification context Data. When this parameter is omitted, the root's node factory is used instead. Constraint_Error is propagated when a handle is invalid. The following figure illustrates rotation example:

The graph is rotated around the feature y. The result is an equivalent graph with only the root node testing y.

### 2.7. Persistence

Persistent storage is used to archive things such as features, training sets, classifiers etc. A persistent storage object usually represents some data base that keeps the archived objects between runs of the application. The persistent storage objects can also be distributed between different application.

Technically a persistent storage abstracts a connection to the data base. Object persistence is implemented by the packages Object.Archived and Persistent.Handle. Any feature, training set, classifier can be placed into a persistent storage under some name. The names are Unicode. Then the application can be finished and another or the same application can be later started. This new application will be able to restore the object from the persistent storage in the exactly same state as it had before. Should the object directly or indirectly use any other objects, they will be stored and restored as necessary together with it. When stored implicitly, these dependent objects become no name in the storage. Such anonymous objects are subject of automatic external garbage collection in the persistent storage. They are removed from the storage when no more referenced by any other objects. Persistent storage interface objects are used to communicate a persistent storage. They can be created using the package Persistent.Handle.Factory.

The package Fuzzy.Persistence provides additional operations for the type Storage_Handle (defined in Persistent.Handle), specific to the objects used in the system:

> `function Get
> ( Storage : Storage_Handle;
> Name : String;
> Parent : Deposit_Handle := Root_Directory
> ) return Handle;`

These functions return a handle to an object resident in the persistent storage specified by the handle Storage. Here Handle is either Classifier_Handle, Feature_Handle, Lecture_Handle, Node_Handle. The parameter Name is the object name. It is safe to call this function several times for same name. All returned handles will point to same object. For a training set an implementation is free either to create a copy of the persistent training set or to allow a direct access to it.

Exceptions
Constraint_Error | Invalid handle, the object specified by Name is not of the expected type. For example, when a classifier is expected, but the name indicates a feature instead. It is also propagated when Parent is not persistent
Data_Error | Inconsistent storage
End_Error | No such object in the storage
Use_Error | The object's class is unknown

> `function Is_In
> ( Storage : Storage_Handle;
> Object : Handle
> ) return Boolean;`

These functions check whether Object persists in Storage. Here Handle is either Classifier_Handle, Feature_Handle, Lecture_Handle, Node_Handle. If Object is not a valid handle, the result is false. Data_Error is propagated when Storage is inconsistent.

> `procedure Put
> ( Storage : in out Storage_Handle;
> Object : in out Handle;
> Name : String;
> Parent : Deposit_Handle := Root_Directory
> );
> procedure Put
> ( Storage : in out Storage_Handle;
> Object : in out Handle
> );`

These procedures store Object in Storage. Here Handle is either Classifier_Handle, Feature_Handle, Lecture_Handle, Node_Handle. The parameters Name and Parent specify the object name and its parent in the storage. When omitted the object is stored anonymous. Anonymous persistent objects are collected when no more used. When Object already persists in Storage and Name is specified, then it is checked that it is same. If this check fails, Name is illegal, or conflicts with the name of another object Name_Error is propagated. When name is not specified no check is made.

Exceptions
Constraint_Error | Invalid handle, Object does not persist in Storage, Parent is not persistent in Storage
Data_Error | Inconsistent storage
Name_Error | Conflicting, empty or illegal name

> `procedure Rename
> ( Storage : in out Storage_Handle;
> Object : in out Handle;
> New_Name : String;
> New_Parent : Deposit_Handle
> );
> procedure` `Rename
> ( Storage : in out Storage_Handle;
> Object : in out Handle;
> New_Name : String
> );`

These procedures change the name of the object. Here Handle is either Classifier_Handle, Feature_Handle, Lecture_Handle, Node_Handle. The parameters Name and Parent specify the object name and its parent in the storage. When renamed object was anonymous before renaming it becomes a named one.

Exceptions
Constraint_Error | Invalid handle, or Object does not persist in Storage, Parent is not persistent in Storage
Data_Error | Inconsistent storage
Name_Error | Conflicting, empty or illegal name

> `procedure Unname
> ( Storage : in out Storage_Handle;
> Object : in out Handle
> );`

These procedures make the object anonymous. Here Handle is either Classifier_Handle, Feature_Handle, Lecture_Handle, Node_Handle. Unnamed objects are automatically deleted when no more in use. Nothing happens if the object is already unnamed or does not persist in Storage. Note that anonymous objects are not deleted as long as they have memory resident counterparts. Note difference between these procedures and Delete called on an object handle. Delete requests object deletion from both memory and persistent storage. Unname does it for persistent storage only. Both may have no immediate effect if the object is still in use.

Exceptions
Constraint_Error | Invalid handle
Data_Error | Inconsistent storage

The example4 illustrates use of a data base for object persistence.

### 2.8. Progress indicators

The package Indicator.Handle provides handles to the objects used to indicate progress of potentially lengthy operations. It defines the type:

> `type Indicator_Handle is tagged private;`

The following operations are defined on Indicator_Handle:

> `procedure Cancel (Viewer : Indicator_Handle);`

This procedure requests operation cancellation. It does not necessarily abort it immediately, instead it postpones it to the time the indicator gets notified through Check, Done or Reset call. For example, if the visual appearance has the cancel button, then the callback of the button should call to Cancel. Viewer can be an invalid handle.

> `procedure Check (Viewer : Indicator_Handle);`

This procedure is called by an operation at a check point. Viewer can be an invalid handle. End_Error is propagated when Viewer aborts the operation.

> `procedure Done (Viewer : Indicator_Handle);`

If an suboperation pending, Done ends it, which corresponds to one check point of the parent operation. Viewer can be an invalid handle. End_Error is propagated when Viewer aborts the operation.

> `procedure Invalidate (Viewer : in out Indicator_Handle);`

This procedure makes handle pointing to nothing. If it was the last reference to the object, the later is destroyed.

> `function Is_Valid (Viewer : Indicator_Handle) return Boolean;`

This function returns true if Viewer is a valid handle.

> `function Ptr (Viewer : Indicator_Handle) return Indicator_Object_Ptr;`

This function returns a pointer to the object referenced by Viewer or null if Viewer is invalid.

> `function Ref (Viewer : Indicator_Object_Ptr)
> return Indicator_Handle;`

This function creates a handle for a pointer to the object.

> `procedure Ref
> ( Handle : in out Indicator_Handle;
> Viewer : Indicator_Object_Ptr
> );`

This procedure assigns a viewer object to handle.

> `procedure Reset
> ( Viewer : Indicator_Handle;
> Total : Natural := 0
> );`

This procedure is called to indicate the start of a suboperation which is later ended by Done. As a whole it corresponds to one check point of the current operation. There can be an unlimited number of nested operation levels. The parameter Total specifies the number of check points or steps of the suboperation. Zero is specified when the total number of steps is unknown, like when a source file is read and the number of lines to expect is unknown. Usually it has no sense for a suboperation to specify Total as 0. Viewer can be an invalid handle. End_Error is propagated when Viewer aborts the operation.

> `No_Indicator : constant Indicator_Handle;`

This is a constant handle to no indication object.

### 2.9. Defuzzifiers

The package Defuzzifier_Handles instantiated in the public part of the specification of Fuzzy.Feature.Output_Handle provides the type Defuzzifier_Handle to used access defuzzifier objects. A defuzzifier translates classifications obtained in terms of linguistic variables into crisp numerical values. Defuzzifiers are usually used in a fuzzy control loop for the outputs which are required to be crisp. There are numerous empirical defuzzification methods relevance of which depends on the application field of application, and is beyond the scope of this document.

The package Defuzzifier_Handles is an instance of the generic package Fuzzy.Feature.Generic_Domain_Float.Generic_Defuzzifier.Generic_Handle:

> `type Defuzzifier_Handle is tagged private;`

The following operations are defined on Defuzzifier_Handle:

> `function Defuzzify
> ( Defuzzifier : Defuzzifier_Handle;
> Value : Variable_Measure
> ) return Measure;`

This function returns defuzzified value of a dimensioned linguistic variable Value. Constraint_Error is propagated when defuzzification is impossible for the method represented by the defuzzifier or else when Defuzzifier is not a valid handle.

> `procedure Delete (Defuzzifier : in out Defuzzifier_Handle);`

This procedure requests deletion of a Defuzzifier. Defuzzifier becomes an invalid handle. The object itself is deleted if possible. Nothing happens if Defuzzifier is not a valid handle.

> `function Get_Class (Defuzzifier : Defuzzifier_Handle)
> return String;`

This function returns the defuzzifier class. It raises Constraint_Error if Defuzzifier is invalid.

> `procedure Invalidate (Defuzzifier : in out Defuzzifier_Handle);`

This procedure detaches handle Defuzzifier from the object (if any) it points to. The result handle cannot be used to access any object. The referenced object is destroyed if it was the last handle.

> `function Is_Valid (Defuzzifier : Defuzzifier_Handle) return Boolean;`

This function checks whether the handle Defuzzifier points to an object.

> `function Ptr (Defuzzifier : Defuzzifier_Handle)
> return Defuzzifier_Object_Ptr;`

This function is used to get a pointer to the object a handle points to. Constraint_Error is propagated if the handle is invalid. The pointer of to the object shall be used no longer the handle it was get from exists.

> `function Ref (Defuzzifier : Defuzzifier_Object_Ptr)
> return Defuzzifier_Handle;`

This function is used to get a handle from a pointer to a object.

> `procedure Ref
> ( Handle : in out Defuzzifier_Handle;
> Defuzzifier : Defuzzifier_Object_Ptr
> );`

This procedure assigns a defuzzifier object to handle.

> `function To_Deposit_Handle (Defuzzifier : Defuzzifier_Handle)
> return Deposit_Handles.Handle;`

This function provides handle conversion from a defuzzifier handle to a general persistent object handle. Constraint_Error is propagated when Defuzzifier is not a valid handle.

> `function To_Defuzzifier_Handle
> ( Defuzzifier : Deposit_Handles.Handle
> ) return Feature_Handle;`

This function provides a backward handle conversion from a general persistent object handle to a defuzzifier handle. Constraint_Error is propagated when Defuzzifier is not a valid handle or does not refer a defuzzifier object.

#### 2.9.1. Defuzzifier factories

The set of child packages of Fuzzy.Feature.Output provide factories of various methods of defuzzification:

- Center_Of_Area is the package containing the factory of center of area defuzzifiers;
- Center_Of_Gravity is one of center of gravity defuzzifiers;
- Discrete_Center_Of_Gravity is one of discrete center of gravity defuzzifiers;
- Leftmost_Max is one of leftmost maximum defuzzifiers;
- Rightmost_Max is one of rightmost maximum defuzzifiers.

All these packages are instances of the generic package Fuzzy.Feature.Generic_Domain_Float.Generic_Defuzzifier.Generic_Handle.Generic_Method. They define the factory function:

> `function Create return Defuzzifier_Handle;`

which returns a handle to the corresponding defuzzifier object.

## 3. Private interfaces

There is a set of packages serving the purpose of implementation of the public interface packages. It can be used to extend the functionality of the software. You can skip this chapter if you do not intend to add new types of features, training sets or classifiers.

The private interface packages are located in the subdirectory private. This subdirectory is further subdivided into:

- private/features contains private interface packages and implementations of the feature objects;
- private/lectures contains ones of the training set object;
- private/classifiers contains ones of the graph-schemes and classifiers.

### 3.1. Feature objects

The package Fuzzy.Feature defines types and subroutines for dealing with feature objects, their values, value constraints and value contexts.

#### 3.1.1. Types

> `type Image_Type is (Has_in, Has_Out, Has_Not, Has_Not_Out);`

This type enumerates four basic fuzzy images. For an original p:

- Has_In denotes the image x(p)↑
- Has_Out does x(p)↑
- Has_Not does x(p)↑
- Has_Not_Out does x(p)↑

> `type Domain_Ptr is
> access constant Fuzzy.Abstract_Edit.User_Data'Class;`

This type provides pointers to feature domain set descriptors. A feature domain set descriptor tells how feature domain values can be specified during I/O. Features of different types may have enumeration, numeric and other kind of domains.

> `type Feature_ID is new Integer;`

Each feature object has an unique identifier. Identifiers are maintained upon construction and destruction of feature objects.

> `type Feature_Object
> ( Name_Length : Positive;
> Cardinality : Positive
> ) is abstract new Deposit with
> record
> ID : Feature_ID;
> Self : Feature_Object_Ptr;
> Name : String (1..Name_Length);
> end record;
> type Feature_Object_Ptr is access Feature_Object'Class;
> for Feature_Object_Ptr'Storage_Pool use Deposit_Ptr'Storage_Pool;`

The type Feature_Object serves as the abstract base type for all feature objects. It has the following discriminants and fields:

- Cardinality is the number of distinct elements in the feature domain set;
- ID is the unique identification number associated with each feature object. It has the type Feature_ID. This field is generated upon object construction in Initialize;
- Name is the feature name. Names are not necessarily unique;
- Name_Length is used to specify the length of the feature name;
- Self is a class-wide pointer to the object. Implementation of a derived type is responsible to set this field immediately after object construction.

Feature_Objects are allocated in a definite storage pool. Features support persistence, for which purpose Feature_Object is derived from the type Object.Archived.Deposit. An implementation should not override the operations Less and Equal defined on the base type. These operations are implemented by Feature_Object so that the feature objects were ordered according to the Is_Computed relation. If Is_Computed (x, y) is true, then Less (x, y) is false. This means that independent features ordered according to Less would appear first.

> `type Feature_Data is abstract
> new Ada.Finalization.Limited_Controlled with private;
> type Feature_Data_Ptr is access Feature_Data'Class;`

The type Feature_Data is the base type for feature-specific types containing writable data. An instance of Feature_Data's descendant can be used to store some context-dependent data related to a feature. For instance, cached values or current constraints of dependent features. See also operations defined on data and derived features which usually require them.

> `type Context_Object is abstract
> new Ada.Finalization.Limited_Controlled with private;
> type Context_Object_Ptr is access Context_Object;`

The type Context_Object contains data of the features referenced in a context. The feature data are allocated when required and then are referenced through Context_Object. All subroutines that query feature values use an instance of Context_Object to keep there the feature data they modify. The feature values are always requested using a context. The context is usually associated with a training set to request the feature values from there. See also operations defined on contexts.

> `type Domain_Subset is array (Positive range <>) of Boolean;
> pragma Pack (Domain_Subset);`

Objects of the type Domain_Subset are crisp subsets of a feature domain. It is implemented as a Boolean array, which for each domain value has true if it is the subset.

> `type Value_Constraint (<>) is
> new Context_Stack_Objects.Pool_Object with private;
> type Value_Constraint_Ptr is access Value_Constraint'Class;
> for Value_Constraint_Ptr'Storage_Pool use Context_Stack;`

Objects of the Value_Constraint type are constraints imposed on the feature value(s). The feature value constraints are allocated on a stack pool and are applied to the feature values stored in a context.

> `Context_Stack : Stack_Storage.Pool
> ( Initial_Size => 2048,
> Items_Number => 16
> );
> package Context_Stack_Objects is
> new Stack_Storage.Mark_And_Release
> ( Stack_Storage.Pool'Class (Context_Stack)
> );
> subtype Context_Snap is Context_Stack_Objects.Pool_Mark;`

Value_Constraint objects should not be explicitly deallocated. Instead of this one should create a Context_Snap object which will automatically save and restore the context state upon its construction and destruction. When created an object of Context_Snap memorizes the state of the context stack pool and restores it upon destruction by deleting all allocated there objects.

> `type Set_Ptr is access Set;`

Set_Ptr is the access type used for feature images.

> `type Input_Parameters is tagged record
> Base : NumberBase := 10;
> Default : Fuzzy_Boolean := Certain_True;
> Mode : Units.Code_Set := Units.UTF8_Set;
> Get_Units : Boolean := False;
> Quote_Units : Boolean := False;
> end record;`

The type Input_Parameters is a record with various fields controlling the way feature values are input:

- Base is one of numeric feature values. It influences only input of integer features values;
- Default is used for intuitionistic sets and classifications. It determines the confidence factors when omitted. If both are, then Default is the result. If only the necessity is omitted then the result necessity is the specified possibility and Default.Necessity;
- Get_Units, when true, forces explicit unit specification. When no unit specified Unit_Error is propagated unless the feature scale is 1 SI. So dimensionless features never need any explicit unit specification;
- Mode is the character set used for parsing unit specifications;
- Quote_Units, when true, requires all unit specifications put in []-brackets.

A value of Input_Parameters is passed as a parameter to all input routines.

> `type Output_Parameters is tagged record
> Base : NumberBase := 10;
> Default : Fuzzy_Boolean := Certain_True;
> Mode : Units.Code_Set := Units.UTF8_Set;
> Abs_Small : Integer :=-MaxSmall;
> Rel_Small : Positive := MaxSmall;
> Put_Units : Boolean := False;
> Put_Plus : Boolean := False;
> Quote_Units : Boolean := False;
> Use_SI : Boolean := False;
> Use_Derived : Boolean := True;
> end record;`

The type Output_Parameters is a record with various fields controlling the way feature values are output:

- Abs_Small together with Rel_Small control the precision of floating-point values output as described in the package Strings_Edit.Float_Edit;
- Base is one of numeric feature values. It influences output of only integer features;
- Default is used for intuitionistic sets and classifications. A range is output as a singleton if the interval consists of only it. Otherwise both the left and right bounds are output. The parameter Default determines the way truth values can be omitted. If the possibility / necessity pair equals to Default then the truth values specification is omitted. If the necessity equals to the possibility and Default.Necessity then only the possibility is output;
- Mode is the character set used in unit specifications;
- Rel_Small together with Abs_Small control the precision of floating-point values output as described in the package Strings_Edit.Float_Edit;
- Put_Plus, if true, forces positive numeric feature values (integer and floating-point ones) be output with + preceding the mantissa;
- Put_Units, if true, forces explicit unit specification output, unless the feature value is output in SI units and the unit is 1 SI. So dimensionless units are always omitted;
- Quote_Units, if true, instructs unit specifications be put in []-brackets if output;
- Use_Derived, if true, allows using derived SI units;
- Use_SI, if true, forces output in SI units. Note that SI output is also used when Put_Units is true and the feature values scale has empty unit text.

#### 3.1.2. Operations

Primitive operations. The following are the primitive operations on Feature_Object. Some of them are abstract and have to be overridden by the derived type.

> `procedure Create_Constraint
> ( Feature : Feature_Object;
> Context : in out Context_Object'Class;
> Allowed : Boolean := True
> );`

This procedure is used to put a new constraint on the feature values in a context. It is dispatching on the parameter Feature so that a feature implementation might override it. The parameter Context is the context. The standard implementation creates a new constraint. The parameter Allowed specifies the initial state of the constraint. If True, then the constraint allows all values allowed at the moment. Otherwise it disallows all feature values. Once created a constraint can be modified using Set_Constraint and Set_Range procedures.

> `function Create_Data (Feature : Feature_Object)
> return Feature_Data_Ptr is abstract;`

This function is used to allocate a data block associated with the feature. The data block is allocated when necessary, a consequent call should return the previously allocated block. The data block can be used to store feature-specific data which have to be in a context. The caller is responsible to free the allocated block. It is legal to return null if no data needed for the feature.

> `procedure Finalize (Feature : in out Feature_Object);`

This procedure is called upon feature finalization. The feature ID is released, so that it can be reused.

> `function Get
> ( Feature : Feature_Object;
> Context : not null access Context_Object'Class;
> Image : Image_Type
> ) return Set is abstract;`

This function returns a fuzzy subset of the feature domain set. The subset corresponds to the image specified by the parameter Image. The parameter Feature is the feature, which value is requested. Context specifies the context. Constraint_Error is propagated when no feature data exits in the context.

> `function Get
> ( Feature : Feature_Object;
> Context : not null access Context_Object'Class;
> Image : Image_Type;
> Value : Positive
> ) return Confidence is abstract;`

This function is defined to be equivalent to:

> `Get (Feature, Data, Image) (Value)`

The result is the possibility (value of the membership function) that the feature image has the specified value in the context. Constraint_Error is propagated when Value is illegal or no feature data exists in the context.

> `function Get_Constraint
> ( Feature : Feature_Object;
> Context : not null access Context_Object'Class
> ) return Domain_Subset;`

This function returns the current constraint on the feature values. That is a Boolean array (1..Cardinality) in which for a feature domain value index true is set when the domain value is allowed by the constraint.

> `function Get_Name (Feature : Feature_Object) return String;`

This function returns the name of a feature. Note that the feature name is not necessarily its external name in a persistent storage. They are unrelated. The same feature may have different external names in different storages. When a feature is stored in a persistent storage its name as returned by this function is stored with it.

> `procedure Get_Range
> ( Source : String;
> Pointer : in out Integer;
> Feature : Feature_Object;
> From : out Positive;
> To : out Positive;
> Exclusive : out Boolean;
> Parameters : Input_Parameters'Class
> ) is abstract;`

This procedure is called to get a range of feature values from the string Source. The process starts from Source (Pointer). Pointer is then advanced to the string position following the value. The procedure is abstract dispatching in the parameter Feature. The result of input is returned through the parameters From and To. From..To is the interval of feature values recognized in Source. From = To if the interval consists of one value. Any implementation should return From ≤ To ≤ Cardinality of the feature. The output parameter Exclusive, when set to true, requires that the domain values from the range collide if repeated unless match exactly. Otherwise, when Exclusive is false, the truth values of the repeated domain values are accumulated. Parameters controls parsing process. It is up to an implementation to decide which fields of Parameters should be used and in which way. An implementation can raise the following exceptions:

Exceptions
Constraint_Error | A value or cardinality is not in range
Data_Error | Syntax error
End_Error | Nothing matched
Layout_Error | Pointer not in Source'First..Source'Last + 1
Unit_Error | An error in units

> `procedure Initialize (Feature : in out Feature_Object);`

This procedure is called upon feature object initialization. The receives a unique ID.

> `function Is_Computed
> ( Feature : Feature_Object;
> Source : Feature_Object'Class
> ) return Boolean is abstract;`

This function can be used to test whether the values of Feature are computed from the values of Source. For any feature it is assumed that Is_Computed (x, x) is true. Furthermore an implementation shall ensure transitivity: Is_Computed (x, y) and Is_Computed (y, z) => Is_Computed (x, z).

> `function Is_Defined
> ( Feature : Feature_Object;
> Context : not null access Context_Object'Class;
> Image : Image_Type
> ) return Boolean is abstract;`

This function can be used to query whether the specified image is defined by the context. An undefined image when requested are returned as all 1. Constraint_Error is propagated when no feature value exists in the context.

> `function Is_Known
> ( Feature : Feature_Object;
> Context : not null access Context_Object'Class;
> Image : Image_Type
> ) return Boolean is abstract;`

This function checks if the specified image is unknown, i.e. has all values of the membership function 1. It returns false then

> `Get (Feature, Context, Image)`

would return all 1. Constraint_Error is propagated when no feature data are present in the context.

> `function Is_Modified (Feature : Feature_Object) return Boolean;`

This function returns false. It implements Object.Archived.Is_Modified. Normally, features are never modified.

> `procedure Put_Range
> ( Destination : in out String;
> Pointer : in out Integer;
> Feature : Feature_Object;
> From : Positive;
> To : Positive;
> Parameters : Output_Parameters'Class;
> Field : Natural := 0;
> Justify : Alignment := Left;
> Fill : Character := ' '
> ) is abstract;`

This procedure places a range of feature values From..To into the output string Destination. Usually singletons are put not as ranges but as singletons. The string is written starting from Destination (Pointer). Pointer is then advanced to position after the end of the output field. Parameters controls the output of feature values. The parameter Field determines the width of the output field. Zero width means the minimal possible width. If Field is not zero Justify determines the way the value should be aligned within the output field. The parameter Fill is then the fill character. Constraint_Error is propagated when From..To is not in 1..Cardinality of Feature. Layout_Error is propagated when Pointer not in Source'First..Source'Last + 1 or there is no room for output.

> `procedure Reset_Modified (Feature : in out Feature_Object);`

This procedure does nothing. It implements Object.Archived.Reset_Modified.

> `procedure Set_Constraint
> ( Feature : Feature_Object;
> Context : in out Context_Object'Class;
> Value : Positive;
> Allowed : Boolean := False
> );`

The effect of this procedure is changing the feature constraint so that it will or not allow Value. It is dispatching on the parameter Feature to support feature-dependent semantics. If no constraint was imposed on the feature it is created using Create_Constraint with the parameter Allowed set to not Allowed. The parameter Value is the number of a domain set element to allow or not. When Allowed is true, the effect of the operation depends on the stack of currently active constraints. It will not allow a value disabled by any constraint before. Constraint_Error is propagated when Value is an illegal domain value.

> `procedure Set_Constraint_Range
> ( Feature : Feature_Object;
> Context : in out Context_Object'Class;
> From : Positive;
> To : Natural;
> Allowed : Boolean := False
> );`

This procedure is equivalent to Set_Constraint called for the range of domain set elements From..To. Nothing happens when the range is empty. Constraint_Error is propagated when the range contains an illegal domain value.

> `procedure Set_Name
> ( Feature : in out Feature_Object;
> Name : String
> );`

This procedure changes the name of Feature.

> `procedure Set_Range
> ( Feature : Feature_Object;
> Context : in out Context_Object'Class;
> From : Positive;
> To : Positive
> );`

The effect of this procedure is changing the feature constraint so that all values outside From..To will be saturated to the closest boundary. If no constraint was imposed on the feature it is created using Create_Constraint with the parameter Allowed set to True. Constraint_Error is propagated when From..To is an illegal domain values range.

Class-wide operations. The following are the operations defined same for all features:

> `function Get_ID (Feature : Feature_Object'Class)
> return Feature_ID;`

This class-wide function returns the feature ID.

Other operations:

> `procedure Free is new Ada.Unchecked_Deallocation (Set, Set_Ptr);`

This procedure is used for deallocation of fuzzy sets allocated on the heap.

> `function Get_Number_Of_Features return Natural;`

This function returns the total number of all features existing at the moment.

> `function To_Deposit_Ptr is
> new Ada.Unchecked_Conversion
> ( Feature_Object_Ptr,
> Deposit_Ptr
> );`

This function provides an upward access type conversion missing in Ada for pool-specific access types.

> `function To_Feature_Object_Ptr (Ptr : Deposit_Ptr)
> return Feature_Object_Ptr;`

This function provides a downward access type conversion. Constraint_Error is propagated when Ptr does not point to a feature object.

> `procedure Finalize (Constraint : in out Value_Constraint);`

This procedure is called upon finalization of a value constraint. The constraint is removed from the context it was applied.

> `Feature_Class : constant String := "Feature.";`

This string is used as the prefix of the names of all feature objects classes.

#### 3.1.3. Independent features

The package Fuzzy.Feature.Generic_Independent provides the base type for features which values does not depend on other features:

> `generic
> type Feature_Type is abstract new Feature_Object with private;
> package Fuzzy.Feature.Generic_Independent is ...`

It defines the abstract data type:

> `type Independent_Feature_Object is abstract
> new Feature_Object with null record;`

Independent features have feature data cached in a context descendant of Lecture_Context.

> `procedure Query
> ( Feature : Independent_Feature_Object;
> Context : in out Context_Object'Class;
> Image : Image_Type;
> Data : in out Cached_Feature_Data'Class
> );`

This procedure is used to query the feature data. Usually it is called once per image and example. The default implementation takes the specified image from the training set and stores it into Data. The derived type may override it if the feature value is computed, for instance.

Also the base type implements Gets, Is_Computed, Is_Defined and Is_Known of Feature_Object. The implementations use Query to determine the feature value if it is not cached in the context.

The package Fuzzy.Feature.Independent is an instance of Fuzzy.Feature.Generic_Independent with Feature_Object as the parameter.

#### 3.1.4. Generic discrete features

The generic package Fuzzy.Feature.Generic_Discrete provides an ability to create a feature object built on the domain of some discrete type:

> `generic
> type Domain_Type is (<>);
> package Fuzzy.Feature.Generic_Discrete is ...`

The formal generic parameter Domain_Type of the package is the discrete type to be used as the feature domain. The implementation is based on the feature objects provided by Fuzzy.Feature.Generic_Independent.

> `function Create (Name : String) return Feature_Handle;`

This function is used to create a feature object based on the discrete type. The parameter Name is the name of the newly created feature. The result is the handle to the created feature.

> `function Is_Discrete (Feature : Feature_Handle) return Boolean
> function Is_Discrete (Feature : Feature_Object'Class) return Boolean;`

This function returns true if Feature is a valid handle to a discrete feature.

#### 3.1.5. Dynamic discrete features

The generic package Fuzzy.Feature.Generic_Discrete has an obvious disadvantage that the domain set of a feature should be known at compile time. Sometimes it is necessary to dynamically create features which domain is unknown until creation time. The package Fuzzy.Feature.Discrete serves this purpose.

> `function Create (Name : String; Domain : String)
> return Feature_Handle;`

This function is used to create a feature object. The parameter Name is the name of the newly created feature. The result is the handle to the created feature. The parameter Domain is the list of feature domain element names separated by commas. Names are case-insensitive, they start from a letter and contain only letters, digits, spaces and underlines. A name may not end with a space or underline. Also if a space or underline appears the next character shall be different. Commas can be surrounded by spaces and tabs in Domain. The whole string shall be matched. Otherwise, Data_Error is propagated. It is also propagated if Domain contains duplicated element names.

> `function Create (Name : String; Domain : Domain_Description'Class)
> return Feature_Handle;`

This function is used to create a feature object. The parameter Name is the name of the newly created feature. The result is the handle to the created feature. The parameter Domain defines the feature domain. It has the type Domain_Description. Constraint_Error is propagated when Domain is empty.

> `function Is_Discrete (Feature : Feature_Handle) return Boolean
> function Is_Discrete (Feature : Feature_Object'Class) return Boolean;`

This function returns true if Feature is a valid handle to a discrete feature.

#### 3.1.6. Generic integer features

The package Fuzzy.Feature.Generic_Domain_Integer is the generic base package of the integer features based upon same integer type:

> `generic
> type Domain_Number is range <>;
> Suffix : String;
> type Interval_Index is (<>);
> type Interval_Map is array (Interval_Index) of Confidence;
> To_Confidence : Interval_Map;
> package Fuzzy.Feature.Generic_Domain_Integer is ...
> subtype Domain_Integer is Number;`

The formal generic parameters are:

- Domain_Number is the type used for domain values;
- Suffix is the class name suffix used for the features that are based upon Domain_Number;
- Interval_Index, Interval_Map, To_Confidence are the parameters used to instantiate Fuzzy.Integers.

The package instantiates some packages required to deal with Domain_Integer:

> `subtype Domain_Integer is Domain_Number;`

It defines the abstract base type for all integer features:

> `type Domain_Feature_Object is abstract
> new Feature_Object with null record;`

All derived types have to implement the following abstract operations:

> `function Classify
> ( Feature : Domain_Feature_Object;
> Value : Domain_Integer
> ) return Fuzzy.Intuitionistic.Classification is abstract;
> function Classify
> ( Feature : Domain_Feature_Object;
> Value : Interval
> ) return Fuzzy.Intuitionistic.Classification is abstract;
> function Classify
> ( Feature : Domain_Feature_Object;
> Value : Fuzzy_Integer
> ) return Fuzzy.Intuitionistic.Classification is abstract;`

These functions should return a intuitionistic classification corresponding to Value. Value can be either a plain number, an interval or a fuzzy number.

> `function To_Set
> ( Feature : Domain_Feature_Object;
> Value : Domain_Integer
> ) return Fuzzy.Intuitionistic.Set is abstract;
> function To_Set
> ( Feature : Domain_Feature_Object;
> Value : Interval
> ) return Fuzzy.Intuitionistic.Set is abstract;
> function To_Set
> ( Feature : Domain_Feature_Object;
> Value : Fuzzy_Integer
> ) return Fuzzy.Intuitionistic.Set is abstract;`

These functions should return a intuitionistic set corresponding to Value. Value can be either a plain number, an interval or a fuzzy number.

However the independent integer features would be most likely derived from a more specialized type defined in the instance of Fuzzy.Feature.Generic_Independent:

> `package Independent_Features is
> new Generic_Independent (Domain_Feature_Object);`

The package Fuzzy.Feature.Domain_Integers is an instance of this generic package with the standard Integer as the parameter.

The package Fuzzy.Feature.Generic_Domain_Integer has the following children:

- Fuzzy.Feature.Generic_Domain_Integer.Generic_Handle provides handles to integer feature types. Its specification is described for the package Fuzzy.Feature.Domain_Integer_Handle, which is an instance of this package for Domain_Integer;
- Fuzzy.Feature.Generic_Domain_Integer.Generic_Integer provides integer features with the domain set consisting of integer singletons forming a range of integer values. Its specification is described for the package Fuzzy.Feature.Integer_Handle, which is an instance of this package for Domain_Integer.

#### 3.1.7. Generic floating-point features

The package Fuzzy.Feature.Generic_Domain_Float is the generic base package of the floating-point features based upon same float type:

> `generic
> type Domain_Number is digits <>;
> Suffix : String;
> type Interval_Index is (<>);
> type Interval_Map is array (Interval_Index) of Confidence;
> To_Confidence : Interval_Map;
> package Fuzzy.Feature.Generic_Domain_Integer is ...
> subtype Domain_Float is Number;`

The formal generic parameters are:

- Domain_Number is the type used for domain values;
- Suffix is the class name suffix used for the features that are based upon Domain_Number;
- Interval_Index, Interval_Map, To_Confidence are the parameters used to instantiate Fuzzy.Floats.

The package instantiates some numerous packages required to deal with Domain_Float:

> `subtype Domain_Float is Domain_Number;`

It defines the abstract base type for all integer features:

> `type Domain_Feature_Object is abstract
> new Feature_Object with null record;`

All derived types have to implement the following abstract operations:

> `function Accumulate
> ( Feature : Domain_Feature_Object;
> Value : Fuzzy.Set
> ) return Variable_Measure is abstract;`

This function evaluates the accumulated result of a fuzzy domain subset. Value is the subset. Constraint_Error is propagated when the cardinality of Value differs from one of Feature.

> `function Classify
> ( Feature : Domain_Feature_Object;
> Value : Domain_Integer
> ) return Fuzzy.Intuitionistic.Classification is abstract;
> function Classify
> ( Feature : Domain_Feature_Object;
> Value : Interval
> ) return Fuzzy.Intuitionistic.Classification is abstract;
> function Classify
> ( Feature : Domain_Feature_Object;
> Value : Fuzzy_Integer
> ) return Fuzzy.Intuitionistic.Classification is abstract;`

These functions should return a intuitionistic classification corresponding to Value. Value can be either a plain number, an interval or a fuzzy number.

> `function Get_Scale (Feature : Domain_Feature_Object)
> return Measure is abstract;`

This function returns the scale of the feature values. The result is a dimensioned value which multiplies dimensionless feature values when no dimension is specified.

> `function Get_Scale_Text
> ( Feature : Domain_Feature_Object;
> Parameters : Output_Parameters'Class
> ) return String is abstract;`

This function returns the scale specification of the feature values. Parameters controls the result. When Parameters.Use_SI is true, or else when the feature was created with no scale string specified, the result is in SI units. Otherwise it the scale string as it was specified in Create. In the former case Parameters.Mode controls the character set to use. Additionally, Parameters.Use_Derived allows use of derived SI units. The result is an empty string if 1 SI should be the result. When the result is not empty, it is surrounded by []-brackets if Parameters.Quote_Units is true. The result can be an empty string.

> `function Get_Variable
> ( Feature : Domain_Feature_Object;
> Value : Positive
> ) return Variable is abstract;`

This function returns a dimensioned linguistic variable by its domain value index. All variables of the domain are numbered starting from 1. Constraint_Error is propagated when Value is not in 1..Feature.Cardinality.

> `function Is_Domain_Linguistic (Feature : Domain_Feature_Object)
> return Boolean is abstract;`

This function returns true if Feature refers a linguistic feature object, which has the linguistic variables named.

> `function To_Set
> ( Feature : Domain_Feature_Object;
> Value : Domain_Integer
> ) return Fuzzy.Intuitionistic.Set is abstract;
> function To_Set
> ( Feature : Domain_Feature_Object;
> Value : Interval
> ) return Fuzzy.Intuitionistic.Set is abstract;
> function To_Set
> ( Feature : Domain_Feature_Object;
> Value : Fuzzy_Integer
> ) return Fuzzy.Intuitionistic.Set is abstract;`

These functions should return a intuitionistic set corresponding to Value. Value can be either a plain number, an interval or a fuzzy number.

> `function Get_Scaled
> ( Source : String;
> Scale : Measure
> ) return Domain_Float;`

This function parses Source for a dimensioned value specification. The value can be specified either as a plain number or as a number followed by a unit specification. The result is the value scaled in the units of Scale. It is the number as found in Source, when Source does not contain any unit specification. Otherwise the number is multiplied to the specified scale and the result is scaled by Scale. Spaces an tabs are blank characters. For numeric input, the package Float_Edit is used. For scale input it is Measures_UTF8_Edit. The unit specification must have non-negative gain otherwise Use_Error is propagated. It also should be compatible with Scale, or else Unit_Error is propagated.

Exceptions
Constraint_Error | A value is not in range
Data_Error | Syntax error
End_Error | No number found
Unit_Error | An error in units, the specified unit is incompatible with Scale
Use_Error | The unit specification has non-positive gain

Note that the independent floating-point features would be most likely derived from a more specialized type defined in the instance of Fuzzy.Feature.Generic_Independent:

> `package Independent_Features is
> new Generic_Independent (Domain_Feature_Object);`

The package Fuzzy.Feature.Domain_Floats is an instance of this generic package with the standard Float as the parameter.

The package Fuzzy.Feature.Generic_Domain_Float has the following children:

- Fuzzy.Feature.Generic_Domain_Float.Generic_Handle provides handles to integer feature types. Its specification is described for the package Fuzzy.Feature.Domain_Float_Handle, which is an instance of this package for Domain_Float;
- Fuzzy.Feature.Generic_Domain_Float.Generic_Float provides floating-point features with the domain set consisting of adjacent intervals. Its specification is described for the package Fuzzy.Feature.Float_Handle, which is an instance of this package for Domain_Float;
- Fuzzy.Feature.Generic_Domain_Float.Generic_Linguistic provides floating-point features with the domain set consisting of linguistic variables having continuous membership functions except for a maybe finite number of point. Its specification is described for the package Fuzzy.Feature.Linguistic_Handle which is an instance of this package for Domain_Float;
- Fuzzy.Feature.Generic_Domain_Float.Generic_Float.Generic_Isosceles_Trapezoids provides floating-point isosceles trapezoid features with the domain set consisting of trapezoid linguistic variables having. Its specification is described for the package Fuzzy.Feature.Isosceles Trapezoids_Handle which is an instance of this package for Domain_Float;
- Fuzzy.Feature.Generic_Domain_Float.Generic_Defuzzifier.Generic_Handle.Generic_Output provides floating-point features with a defuzzification method attached. Its specification is described for the package Fuzzy.Feature.Output_Handle which is an instance of this package for Domain_Float.

#### 3.1.8. Binary features

The package Fuzzy.Feature.Binary provides binary derived features. The domain of a binary feature is {0,1}. There are n different binary features of a source feature. Where n is binary logarithm of the feature domain cardinality.

> `function Create (Feature : Feature_Handle)
> return Bounded_Array;`

This function creates all possible derived binary features of the feature specified by the parameter Feature. The newly created features will have names of the source feature with the suffix ".n" added, where n is the order of the created feature. The result is an array of handles to created features. Constraint_Error is propagated if Feature is invalid.

> `function Create
> ( Name : String;
> Feature : Feature_Handle
> ) return Feature_Handle;`

This function creates a single derived binary feature. When Feature indicates a non-binary feature, the result is the first binary feature derived from it. When Feature indicates a binary feature, the result is the binary feature second to it. The parameter Name specifies the name of the result. End_Error is propagated when the feature cannot be created because Feature is already the last possible binary feature. Constraint_Error is propagated if Feature is invalid.

> `function Create
> ( Name : String;
> Feature : Feature_Handle
> Bit_Position : Natural
> ) return Feature_Handle;`

This function creates a single derived binary feature. The parameter Name specifies the name of the result. The parameter Bit_Position specifies the bit of the domain value position of the. The position of the most significant bit is 0. End_Error is propagated when the feature cannot be created because Bit_Position is bigger than the least significant bit. Constraint_Error is propagated if Feature is invalid.

> `function Get_Bit_Position (Feature : Feature_Handle / Feature_Object'Class)
> return Natural;`

This function returns feature's bit position as in Create. Constraint_Error is propagated if Feature is invalid or does not refer a binary feature.

> `function Get_Source (Feature : Feature_Handle / Feature_Object'Class)
> return Feature_Handle;`

This function returns a handle to the feature from which Feature was derived. Constraint_Error is propagated if Feature is invalid or does not refer a binary feature.

> `function Is_Binary (Feature : Feature_Handle / Feature_Object'Class)
> return Boolean;`

This function checks if Feature refers to a binary feature.

The child package Fuzzy.Feature.Binary.Mutually_Independent provides binary derived features, which are same as ones provided in the parent package, except that they are mutually independent.

> `function Create (Feature : Feature_Handle)
> return Bounded_Array;`

This function creates all possible derived independent binary features of the feature specified by the parameter Feature. The newly created features will have names of the source feature with the suffix ".n" added, where n is the order of the created feature. The result is an array of handles to created features. Constraint_Error is propagated if Feature is invalid.

> `function Create
> ( Name : String;
> Feature : Feature_Handle
> ) return Feature_Handle;`

This function creates a single derived independent binary feature. When Feature indicates a non-binary feature, the result is the first binary feature derived from it. When Feature indicates a binary feature, either dependent or independent, the result is the independent binary feature second to it. The parameter Name specifies the name of the result. End_Error is propagated when the feature cannot be created because Feature is already the last possible binary feature. Constraint_Error is propagated if Feature is invalid.

> `function Create
> ( Name : String;
> Feature : Feature_Handle
> Bit_Position : Natural
> ) return Feature_Handle;`

This function creates a single derived independent binary feature. The parameter Name specifies the name of the result. The parameter Bit_Position specifies the bit of the domain value position of the. The position of the most significant bit is 0. End_Error is propagated when the feature cannot be created because Bit_Position is bigger than the least significant bit. Constraint_Error is propagated if Feature is invalid.

> `function Get_Source (Feature : Feature_Handle / Feature_Object'Class)
> return Feature_Handle;`

This function returns a handle to the feature from which Feature was derived. Constraint_Error is propagated if Feature is invalid or does not refer a binary feature.

> `function Is_Bit (Feature : Feature_Handle / Feature_Object'Class)
> return Boolean;`

This function checks if Feature refers to an independent binary feature.

#### 3.1.9. Classificatory features

The package Fuzzy.Feature.Classificatory provides classificatory features. A classificatory feature uses some classifier to classify data. The result of classification is the feature value.

> `function Create
> ( Name : String;
> Classifier : Classifier_Handle;
> Generalize : Generalization_Mode := Linear;
> Threshold : Confidence := Confidence'First
> ) return Feature_Handle;`

This function creates a classificatory feature. The parameter Name specifies the feature name. The parameter Classifier is one to use in classifications. The parameter Generalize advises the classifier how to deal with the examples missing in the training set. It has the type Generalization_Mode. The parameter Threshold specifies the threshold applied during classifications. These two parameters are passed to Classify operation of Classifier. Constraint_Error is propagated when Classifier is invalid.

> `function Get_Classifier (Feature : Feature_Handle) return Classifier_Handle;
> function Get_Classifier (Feature : Feature_Object'Class) return Classifier_Handle;`

These functions return the classifier used by the classificatory feature. Do not modify the result of this function. That should not necessary influence the classifier used by the feature. For that Learn or Set_Classifier procedures should be used instead. Constraint_Error is propagated if Feature is invalid or does not point to a classificatory feature.

> `function Get_Generalization (Feature : Feature_Handle) return Generalization_Mode;
> function Get_Generalization (Feature : Feature_Object'Class) return Generalization_Mode;`

This function returns the current generalization mode. Constraint_Error is propagated if Feature is invalid or does not point to a classificatory feature.

> `function Get_Threshold (Feature : Feature_Handle) return Confidence;
> function Get_Threshold (Feature : Feature_Object'Class) return Confidence;`

This function returns the current threshold used by the classificatory feature. Constraint_Error is propagated if Feature is invalid or does not point to a classificatory feature.

> `function Is_Classificatory (Feature : Feature_Handle) return Boolean;
> function Is_Classificatory (Feature : Feature_Object'Class) return Boolean;`

This function checks if Feature refers a classificatory feature.

> `procedure Learn
> ( Feature : in out Feature_Handle;
> Lesson : Lecture_Handle;
> Features : Feature_Array;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Threshold : Confidence := Confidence'First;
> Viewer : Indicator_Handle
> );
> procedure Learn
> ( Feature : in out Feature_Handle;
> Lesson : Lecture_Handle;
> Features : Feature_Array;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Threshold : Confidence := Confidence'First;
> Viewer : not null access Indicator_Object'Class :=
> Negleter'Access
> );
> procedure Learn
> ( Feature : in out Feature_Object'Class;
> Lesson : Lecture_Handle;
> Features : Feature_Array;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Threshold : Confidence := Confidence'First;
> Viewer : Indicator_Handle
> );
> procedure Learn
> ( Feature : in out Feature_Object'Class;
> Lesson : Lecture_Handle;
> Features : Feature_Array;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Threshold : Confidence := Confidence'First;
> Viewer : not null access Indicator_Object'Class :=
> Negleter'Access
> );`

These procedures modify the classifier of the feature according to new training examples from the set Lesson. For further information see the package Fuzzy.Classifier.Handle.

Exceptions
Constraint_Error | An invalid handle, Feature does no refer a classificatory feature
Data_Error | I/O error when writing into the training set
End_Error | Operation was aborted by the indication object. Some examples have been used in learning, some not
Use_Error | One of the features specified depends on the classifier. Circular dependencies are not allowed. This exception may also indicate that the classified does not support incremental learning.

> `procedure Learn
> ( Feature : in out Feature_Handle;
> Context : in out Training_Data'Class;
> Features : Feature_Array;
> From : Positive := 1;
> To : Positive := Positive'Last;
> );
> procedure Learn
> ( Feature : in out Feature_Object'Class;
> Context : in out Training_Data'Class;
> Features : Feature_Array;
> From : Positive := 1;
> To : Positive := Positive'Last;
> );`

These procedures modify the classifier of the feature according to new training examples from the set Lesson associated with Context. For further information see the package Fuzzy.Classifier.Handle. Contraint_Error exception may propagate when the parameter Context refers to incompatible training data.

> `procedure Set_Classifier
> ( Feature : in out Feature_Handle;
> Classifier : Classifier_Handle
> );
> procedure Set_Classifier
> ( Feature : in out Feature_Object'Class;
> Classifier : Classifier_Handle
> );`

This procedure is used to change the classifier associated with a classificatory feature. The new classifier is specified by the parameter Classifier. It should have exactly the same class-feature as the old one. Otherwise Constraint_Error is propagated. It is also propagated if Feature is invalid or does not point to a classificatory feature or Classifier is invalid.

> `procedure Set_Generalization
> ( Feature : in out Feature_Handle;
> Generalize : Generalization_Mode
> );
> procedure Set_Generalization
> ( Feature : in out Feature_Object'Class;
> Generalize : Generalization_Mode
> );`

This procedure is used to change the generalization mode for classifier associated with a classificatory feature. Constraint_Error is propagated when Feature is invalid or does not point to a classificatory feature.

> `procedure Set_Threshold
> ( Feature : in out Feature_Handle;
> Threshold : Confidence
> );
> procedure Set_Threshold
> ( Feature : in out Feature_Object'Class;
> Threshold : Confidence
> );`

This procedure is used to change the threshold for classifier associated with a classificatory feature. Constraint_Error is propagated when Feature is invalid or does not point to a classificatory feature.

#### 3.1.10. Feature data

The package Fuzzy.Feature defines an abstract type Feature_Data used to store feature values and constraints in a context. It is a limited controlled type with the primitive operation:

> `procedure Undefine
> ( Data : in out Feature_Data;
> Context : in out Context_Object'Class
> ) is abstract;`

This procedure is used to undefine a feature in the context. Defined feature images are usually taken directly from the context. Undefined images are requested from the training set associated with the context.

The child package Fuzzy.Feature.Data provides an implementation of Feature_Data, the type Cached_Feature_Data:

> `type Image_Flags is array (Image_Type) of Boolean;
> type Cached_Feature_Data (Cardinality : Positive) is
> new Feature_Data with
> record
> Known : Image_Flags := (others => False);
> Defined : Image_Flags := (others => False);
> Has_In : Set (1..Cardinality);
> Has_Out : Set (1..Cardinality);
> Has_Not : Set (1..Cardinality);
> Has_Not_Out : Set (1..Cardinality);
> end record;`

#### 3.1.11. Feature contexts

The package Fuzzy.Feature defines an abstract limited controlled type Context_Object with the primitive operations:

> `function Get_Data
> ( Context : not null access Context_Object;
> Feature : Feature_Object'Class
> ) return Feature_Data_Ptr is abstract;`

This function is used to get the data block associated with the feature. The data block is allocated when necessary using Create_Data. So this function should never fail. This function is dispatching on the context parameter.

> `procedure Set_Data
> ( Context : in out Context_Object;
> Feature : Feature_Object'Class;
> Data : in out Feature_Data_Ptr
> ) is abstract;`

This procedure places a newly allocated data block of a feature into a context. The context is responsible to free the object pointed by Data upon context destruction. This procedure has to be implemented by a type derived from Context_Object. The object pointed by Data is destroyed if any exceptions propagates. Program_Error is propagated when Context already has a data block for Feature.

The package Fuzzy.Feature. Context provides an implementation of Context_Object based on training sets:

> `type Lecture_Context (Lesson : not null access Lecture_Object'Class) is
> new Context_Object with
> record
> Example : Positive := 1;
> end record;`

The discriminant Lesson is the training set associated with the context. The following operations are defined on Lecture_Context:

> `function Get
> ( Context : not null access Lecture_Context;
> Example : Positive;
> Feature : Feature_Object'Class;
> Image : Image_Type
> ) return Set;`

This function returns the image specified by the parameter Image for Feature in the example Example. The result is the image, a fuzzy subset of the feature domain.

> `function Get
> ( Context : not null access Lecture_Context;
> Example : Positive;
> Feature : Feature_Object'Class;
> Image : Image_Type;
> Value : Positive
> ) return Confidence;`

This function is an equivalent to:

> `Get (Context, Example, Feature, Image) (Value)`

It returns the possibility of Value in the specified image. Value is the positive number of the feature domain set element. Constraint_Error is propagated if Value is illegal.

> `function Is_Defined
> ( Context : not null access Lecture_Context;
> Example : Positive;
> Feature : Feature_Object'Class;
> Image : Image_Type
> ) return Boolean;`

This function can be used to query whether an image of is defined by the training set. The result is true if the image is present in the current example.

> `function Is_Known
> ( Context : not null access Lecture_Context;
> Example : Positive;
> Feature : Feature_Object'Class;
> Image : Image_Type
> ) return Boolean;`

This function checks if the specified image is unknown. An image is unknown if Get would return all 1.

> `procedure Select_Example
> ( Context : in out Lecture_Context;
> Example : Positive
> );`

This procedure is used to select an example of the training set associated with the context. It does nothing if the example is already selected. Otherwise all cached context data are invalidated.

### 3.2. Training set objects

The package Fuzzy.Lecture defines the type Lecture_Object serving as the abstract base type for all training set objects:

> `type Lecture_Object is abstract new Deposit with private;
> type Lecture_Object_Ptr is access Lecture_Object'Class;
> for Lecture_Object_Ptr'Storage_Pool use Deposit_Ptr'Storage_Pool;`

Training sets support persistence, for which purpose Lecture_Object is derived from the type Object.Archived.Deposit. Types derived from Lecture_Object provide implementations of various training sets by overriding the abstract primitive operations of Lecture_Object.

#### 3.2.1. Primitive operations

The following operations are abstract and have to be implemented by derived types:

- Get, requests an image;
- Get_Examples_Number determines the number of examples in a set;
- Is_Defined queries whether an image was cached;
- Is_Known tests whether Get would return all 1;
- Put (two variants) place or modifies an image.

> `procedure Finalize (Lesson : in out Lecture_Object);`

The training set destructor has to be called from a derived type's Finalize when overridden.

> `function Get
> ( Lesson : Lecture_Object;
> Example : Positive;
> Feature : Feature_Object'Class;
> Image : Image_Type
> ) return Set is abstract;`

This function returns the requested image for Feature in the example Example. The parameter Image specifies the image to get. This function should not be called directly by clients. It has to be overridden by a derived type. A class-wide variant has to be used instead. An implementation may use Data_Error exceptions to indicate I/O errors. Note that a non-existing value of Example should not cause exceptions because images of such examples should be returned as all 1.

> `function Get_Examples_Number (Lesson : Lecture_Object)
> return Natural is abstract;`

This function returns the number of examples in Lesson. Data_Error is propagated on I/O errors.

> `function Get_Feature
> ( Lesson : Lecture_Object;
> Index : Positive
> ) return Feature_Handle is abstract;`

This function returns a handle to the feature corresponding to the column Index of the set Lesson. Columns are enumerated starting with 1. Constraint_Error is propagated if Index is too high. Data_Error is propagated on I/O errors.

> `function Get_Features (Lesson : Lecture_Object)
> return Bounded_Array is abstract;`

This function returns the features defined by Lesson. A feature is in the set if the set defines at least one image of this feature. This function returns an array of the features in the set. The order of the features in the array reflects their order in the set (if any). Data_Error is propagated on I/O errors.

> `function Get_Features_Number (Lesson : Lecture_Object)
> return Natural is abstract;`

This function returns the total number of the features in the set Lesson. Data_Error is propagated on I/O errors.

> `procedure Initialize (Lesson : in out Lecture_Object);`

When overridden this function has to be called from there.

> `function Is_Defined
> ( Lesson : Lecture_Object;
> Example : Positive;
> Feature : Feature_Object'Class;
> Image : Image_Type
> ) return Boolean is abstract;`

This function is used to query whether an image is defined by the training set. Undefined images when requested are returned as unknown by the Get-function, i.e. as a subset with all 1. See also Query which is called for an undefined image to get it from an external source. Normally an implementation returns false, when the image was not yet cached, and true otherwise. Data_Error indicates an I/O fault.

> `function Is_Known
> ( Lesson : Lecture_Object;
> Example : Positive;
> Feature : Feature_Object'Class;
> Image : Image_Type
> ) return Boolean is abstract;`

This function checks if the specified image is unknown, i.e. has all values of the membership function 1. This function should never be called directly, but through its class-wide proxy. An implementation should return false if the corresponding Get would return all 1. The reason why Get and Is_Known are separate is to avoid caching unknown examples and so save memory. Data_Error is propagated on I/O errors.

> `procedure Put
> ( Lesson : in out Lecture_Object;
> Example : Positive;
> Feature : Feature_Object'Class;
> Image : Image_Type;
> Value : Set
> ) is abstract;`

This procedure sets the specified image of Feature in the example Example. The image is specified by the parameter Image. Initially the distribution is all 1 (unknown). Constraint_Error is propagated when Value has wrong cardinality. Data_Error is propagated on I/O errors.

> `procedure Put
> ( Lesson : in out Lecture_Object;
> Example : Positive;
> Feature : Feature_Object'Class;
> Image : Image_Type;
> Value : Positive
> ) is abstract;`

This procedure sets only one point of the specified image. The parameter Value indicates which feature domain element to set. The effect is that the element will fully belong to the image (set to 1). When a point of an undefined image is set, other points are initialized with 0. Constraint_Error is propagated when Value is greater than the cardinality of the feature. Data_Error is propagated on I/O errors.

> `procedure Query
> ( Lesson : in out Lecture_Object;
> Example : Positive;
> Feature : Feature_Object'Class
> );`

This procedure is used to query the data missing in the training set. When Get or Is_Known function determine some data missing they call Query. The callee may get the data from some external source and then put it into the training set using an appropriate Put procedure. The callee may also leave the image undefined, because the caller is not allowed to call Query more than once per call, so that no infinite recursion may happen. For this it calls a dispatching (primitive) Get-function, which would deal with undefined image by returning unknown result. The base type implementation has no effect. A derived type may override it to provide a user dialogue or a data base support.

> `procedure Set_Undefined
> ( Lesson : in out Lecture_Object;
> Example : Positive;
> Feature : Feature_Object'Class
> ) is abstract;
> procedure Set_Undefined
> ( Lesson : in out Lecture_Object;
> Feature : Feature_Object'Class
> ) is abstract;`

This procedure sets the images of Example undefined. Undefined images requested for the training sets using querying mechanism. Data_Error is propagated on I/O errors. When the parameter Example is omitted, all examples are set undefined. It should have the effect of decoupling the training set from the feature, so that the set will no more refer it.

Non-abstract operations:

> `procedure Begin_Bulk_Update (Lesson : in out Lecture_Object);`

This procedure initiates a bulk update of the training set. A call to Begin_Bulk_Update is matched but End_Bulk_Update. Some implementations may take advantage of knowing about an incoming massive update, for example when the training set implementation is based on transactions. Begin_Bulk_Updatewould open a transaction and End_Bulk_Update would commit it. The implementation may propagate for The default implementation does nothing.

Exceptions
Data_Error | I/O error
Use_Error | Nested call to Begin_Bulk_Update. The implementation may choose to allow nested bulk operations. In that case it need not to propagate this exception

> `procedure End_Bulk_Update (Lesson : in out Lecture_Object);`

This procedure ends block update of the training set initiated by Begin_Bulk_Update. The default implementation does nothing.

Exceptions
Data_Error | I/O error
Use_Error | No bulk operation pending

#### 3.2.2. Class-wide operations

> `procedure Attach
> ( Lesson : in out Lecture_Object'Class;
> Observer : Lecture_Observer_Lists.Doubly_Linked.Item
> );`

This procedure is called to attach a Lecture_Observer to the training set.

> `procedure Copy
> ( Target : in out Lecture_Object'Class;
> Source : Lecture_Object'Class;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Viewer : not null access Indicator_Object'Class :=
> Negleter'Access
> );`

This procedure copies all examples of the training set Source into the set Target. It adds the examples to the end of Target. The parameters From, To determine the range of examples to copy. The parameter Viewer specifies an indication object. The progress of a copy operation is measured in examples. End_Error is propagated when the operation is aborted by Viewer. In this case the Target may receive only a part of the examples from Source. Data_Error is propagated on I/O errors.

> `procedure Generic_Restore
> ( Source : String;
> Pointer : in out Integer;
> Class : String;
> List : Deposit_Container'Class;
> Lesson : in out Lecture_Object'Class
> );`

This is a class-wide implementation of Object.Archived.Restore that should work for any implementation of training set. It can be called from an override of Object.Archived.Restore when no more efficient way is available.

> `procedure Generic_Store
> ( Destination : in out String;
> Pointer : in out Integer;
> Lesson : Lecture_Object'Class
> );`

This is a class-wide implementation of Object.Archived.Store working with Generic_Restore.

> `function Get
> ( Lesson : not null access Lecture_Object'Class;
> Example : Positive;
> Feature : Feature_Object'Class;
> Image : Image_Type
> ) return Set;`

This function returns the distribution of the possibilities of the requested image. There are four images, the parameter Image specifies which one has to be returned. The result is a fuzzy subset of the domain of Feature. The parameter Example is the example number. The querying mechanism is used for undefined values. Data_Error is propagated on I/O errors.

> `function Is_Known
> ( Lesson : not null access Lecture_Object'Class;
> Example : Positive;
> Feature : Feature_Object'Class;
> Image : Image_Type
> ) return Boolean;`

This function checks if the specified image is unknown, i.e. has all values of the membership function 1, i.e. false when

> `Get (Lesson, Example, Feature, Image)`

would return all 1. The querying mechanism is used for undefined values. Data_Error is propagated on I/O errors.

> `procedure Notify_Changed
> ( Lesson : Lecture_Object'Class;
> Example : Positive;
> Feature : Feature_Object'Class;
> Image : Image_Type
> );`

This procedure is to be called from an implementation of Put in order to notify Lecture_Observer objects monitoring the training set Lesson.

> `procedure Notify_New
> ( Lesson : Lecture_Object'Class;
> Feature : Feature_Object'Class
> );`

This procedure is to be called from an implementation of Put when a new feature is added to the training set to notify Lecture_Observer objects.

> `procedure Notify_Undefined
> ( Lesson : Lecture_Object'Class;
> Example : Positive;
> Feature : Feature_Object'Class
> );
> procedure Notify_Undefined
> ( Lesson : Lecture_Object'Class;
> Feature : Feature_Object'Class
> );`

This procedure is to be called from an implementation of Set_Undefined to notify Lecture_Observer objects monitoring the training set Lesson.

#### 3.2.3. Other operations and types

> `function Get_Number_Of_Lectures return Natural;`

This function returns the total number of training sets.

> `function To_Deposit_Ptr is
> new Ada.Unchecked_Conversion
> ( Lecture_Object_Ptr,
> Deposit_Ptr
> );`

This function provides an upward access type conversion missing in Ada for pool-specific access types.

> `function To_Lecture_Object_Ptr (Ptr : Deposit_Ptr)
> return Lecture_Object_Ptr;`

This function provides a downward access type conversion. Constraint_Error is propagated when Ptr does not point to a training set object.

> `Lecture_Class : constant String := "Lecture.";`

This string is used as the prefix of the names of all training set objects classes.

> `type Lecture_Observer is abstract new Object.Entity with null record;`

The type Lecture_Observer is used in order to monitor changes of the training set. It has the following operations to override:

> `procedure Added
> ( Observer : in out Lecture_Observer;
> Lesson : Lecture_Object'Class;
> Feature : Feature_Object'Class
> ) is abstract;`

This procedure is called when a new feature is added to Lesson.

> `procedure Changed
> ( Observer : in out Lecture_Observer;
> Lesson : Lecture_Object'Class;
> Example : Positive;
> Feature : Feature_Object'Class;
> Image : Image_Type
> ) is abstract;`

This procedure is called when a training example is changed.

> `procedure Deleted
> ( Observer : in out Lecture_Observer;
> Lesson : Lecture_Object'Class;
> Example : Positive;
> Feature : Feature_Object'Class
> ) is abstract;`

This procedure is called when a training example is set to undefined for a feature.

> `procedure Deleted
> ( Observer : in out Lecture_Observer;
> Lesson : Lecture_Object'Class;
> Feature : Feature_Object'Class
> ) is abstract;`

This procedure is called when a feature is removed from the training set.

> `package Lecture_Observer_Lists is
> new Generic_Doubly_Linked (Lecture_Observer'Class);`

The package Lecture_Observer_Lists has a package instance Doubly_Linked that provides doubly-linked lists of Lecture_Observer.

#### 3.2.4. Subrange training set

The package Fuzzy.Lecture.Subrange provides derived training set that represents a range of the reference set examples:

> `function Create
> ( Source : Lecture_Handle;
> From : Positive;
> To : Natural := Positive'Last
> ) return Lecture_Handle;`

This function creates a new training set. The training set contains the examples From..To of Source. The parameter To may be less than From to indicate empty range. It can also be greater than the total examples number of Source. Updating the training set also does the source set. An attempt to modify the Source set outside the examples range causes Use_Error exception. Examples outside the range when read considered undefined. The training subrange set are enumerated from 1. Constraint_Error is propagated when Source is not a valid handle.

> `Class : constant String := ...;`

This constant is the training set object's class.

#### 3.2.5. Composite training set

The package Fuzzy.Lecture.Composite provides derived training set composed of the examples of one or more training sets. The package declares:

> `type Feature_To_Lecture_Pair is record
> Feature : Feature_Handle;
> Lecture : Lecture_Handle;
> end record;
> type Feature_To_Lecture_Map is
> array (Positive range <>) of Feature_To_Lecture_Pair;`

> `function Create
> ( Mapping : Feature_To_Lecture_Map
> ) return Lecture_Handle;`

This function creates a new training set. The training set contains the examples from the sets specified in Mapping. For each feature in Mapping the training set contains the examples from the set mapped by the feature. Constraint_Error is propagated when Mapping contains invalid handles. Data_Error is propagated when Mapping has non-unique features.

> `Class : constant String := ...;`

This constant is the training set object's class.

### 3.3. Classifiers

The package Fuzzy.Classifier defines the interface of abstract fuzzy classifiers.

#### 3.3.1. Types

> `type Classifier_Object is abstract new Deposit with null record;
> type Classifier_Object_Ptr is access Classifier_Object'Class;`

The objects derived from Classifier_Object implement fuzzy classifiers.

> `type Divergence is new Float;`

This type is used to represent truth values used to quantify differences between fuzzy logical values. Divergence is exchangeable with Confidence and is only used where the values of truth factors need to be processed numerically.

> `package Divergence_Ranges is new Intervals.Floats (Divergence);
> subtype Divergence_Range is Divergence_Ranges.Interval;`

The type Divergence_Range is type an interval with Divergence bounds. It is obtained through an instantiation of the package Intervals.Floats. Values of Divergence_Range are substitutes for ones of Fuzzy_Boolean when processed numerically.

> `type Divergence_Vector is
> array (Integer range <>) of Divergence_Range;`

This type is an array of Divergence_Range intervals.

> `type Divergence_Function is not null access
> function (Left, Right : Fuzzy_Boolean)
> return Divergence_Range;`

This is the type of a pointer to the function used to compare fuzzy logical values (Fuzzy_Boolean). The function is used to estimate difference between two Fuzzy_Boolean values.

> `type Generalization_Mode is (None, Nearest, Linear);`

This discrete type defines the modes of generalization used during classification:

- None is no generalization, classification repeats the training set;
- Nearest is a generalization when examples missing in the training set are classified as the examples from the set nearest to them in the sense defined by the classifier;
- Linear is a generalization when missing examples classification is linearly interpolated between two examples around it. The order is again determined by the classifier.

> `type Classification_Parameters
> ( Lesson : not null access Lecture_Object'Class;
> Cardinality : Positive
> ) is new Fuzzy.Feature.Context.Lecture_Context (Lesson) with
> record
> Threshold : Confidence;
> Image : Image_Type;
> Ready : Boolean;
> Result : Classification (Cardinality);
> end record;`

Objects of this type are used during classification. Because classification is usually a recursively defined process the data common across recursive calls are stored in Classification_Parameters to optimize stack use. The fields and discriminants are:

- Cardinality is one of the class feature;
- Image is the type of the images selected for classification;
- Lesson is a pointer to the training set;
- Ready is the result readiness flag. When set to true, it is assumed that the field Result contains a completed result;
- Result is the accumulated classification result;
- Threshold specifies the truncation level. All confidence factors less than Threshold are treated as 0. Higher values of Threshold may speed up classification, though make it less precise.

> `type Training_Data
> ( Lesson : not null access Lecture_Object'Class;
> Length : Natural;
> Viewer : not null access Indicator_Object'Class
> ) is new Fuzzy.Feature.Context.Lecture_Context (Lesson) with
> record
> Threshold : Confidence := Confidence'First;
> Equivalence : Confidence := Default_Equivalence;
> Set_Name : String (1..Length);
> end record;`

This structure is used during learning too keep training data and parameters:

- Equivalence is threshold of quality by which features are selected. When two features have separation qualities different less than Equivalence, they are considered of equal quality. When Equivalence is Confidence'Last no features selection happens.
- Lesson is a pointer to the training set;
- Set_Name is the external name of the training set, UTF-8 encoded. The set name is optional, used in the generated classifier to hint the set. When empty, it is unused;
- Threshold specifies the truncation level. All confidence factors less than Threshold are treated as 0. Higher values of Threshold may speed up training, though make it less precise;
- Viewer points to a progress indication object.

#### 3.3.2. Primitive operations of classifiers

The following are the primitive operations of the type Classifier_Object. They are abstract and have to be implemented in derived types.

> `function Classify
> ( Classifier : Classifier_Object;
> Context : not null access Classification_Parameters'Class;
> Complement : Boolean := False
> ) return Classification is abstract;`

This function uses Classifier to classify one example from a fuzzy training set. The parameter Context is the classification parameters. The function classifies only one example from the training set associated with Context. The parameter Complement, when true, indicates that the complement of the event behind the example has to be classified.

Exceptions
Constraint_Error | Invalid classifier
Data_Error | I/O error when reading from the training set

> `function Estimate
> ( Classifier : Classifier_Object;
> Context : not null access Classification_Parameters'Class;
> Complement : Boolean := False
> ) return Fuzzy.Intuitionistic.Set is abstract;`

This function uses Classifier to estimate one example from a fuzzy training set. The parameters are same as in Classify.

Exceptions
Constraint_Error | Invalid classifier
Data_Error | I/O error when reading from the training set

> `function Get_Classes (Classifier : Classifier_Object)
> return Feature_Handle is abstract;`

This function returns a handle to the class-feature of the Classifier. Constraint_Error is propagated when Classifier is invalid.

> `procedure Get_Examples
> ( Classifier : Classifier_Object;
> Lesson : in out Lecture_Handle;
> Viewer : not null access Indicator_Object'Class := Negleter'Access
> ) is abstract;`

This procedure extracts training examples from Classifier. Each one should have a corresponding training set from which the classifier can be restored. The extracted examples are added to the training set specified by the handle Lesson. The parameter Viewer specifies an indication object. The progress of is measured in percent.

Exceptions
Constraint_Error | Invalid classifier
Data_Error | I/O error when writing into the training set
End_Error | Operation was aborted by the indication object

> `function Get_Features (Classifier : Classifier_Object)
> return Fuzzy.Feature.Handle.Container.Set is abstract;`

This function returns the set of the features used by Classifier. This set contains the class-feature.

> `function Get_Training_Set_Name (Classifier : Classifier_Object)
> return String;`

This function returns the name of the training set used to build the Classifier. The name is an UTF-8 encoded string that identifies the training set, usually in an external storage. The name may indicate no set or another set, and should be considered as a hint. The result is an empty string if no set name was set.

> `procedure Learn
> ( Classifier : in out Classifier_Object;
> Context : in out Training_Data'Class;
> Features : Feature_Array;
> From : Positive := 1;
> To : Positive := Positive'Last;
> ) is abstract;`

This procedure modifies Classifier according to the training examples from the training set associated with Context. The parameter Context specifies the training data. The parameter Features defines the sequence of features. The list may contain No_Feature elements, which are ignored. The sequence may be empty. The parameters From and To specify the range of training examples to learn from. Usually it is the whole set. The parameter To can be greater than the total number of examples.

Exceptions
Constraint_Error | Invalid classifier or context
Data_Error | I/O error when reading from the training set
End_Error | Operation was aborted by the indication object

#### 3.3.3. Class-wide operations and data

> `function Classify
> ( Classifier : Classifier_Object'Class;
> Lesson : Lecture_Handle;
> Example : Positive;
> Generalize : Generalization_Mode := Linear;
> Threshold : Confidence := Confidence'First;
> Complement : Boolean := False
> ) return Classification;
> function Estimate
> ( Classifier : Classifier_Object'Class;
> Lesson : Lecture_Handle;
> Example : Positive;
> Generalize : Generalization_Mode := Linear;
> Threshold : Confidence := Confidence'First;
> Complement : Boolean := False
> ) return Intuitionistic.Set;
> `

These procedures are class-wide variants of Classify and Estimate. They call to the corresponding dispatching variant with the parameter Context constructed out of Lesson, a handle to the training set. Constraint_Error is propagated when Lesson is invalid. The example to classify is specified by the parameter Example. Images not represented in the set are assumed unknown. The result of classification is an intuitionistic classification pair of distributions of over the domain set of the class-feature. The parameter Generalize advises the classifier how to deal with the examples missing in the training set. It has the type Generalization_Mode. The parameter Threshold specifies the truncation level. All confidence factors less than Threshold are treated as 0. Higher values of Threshold may speed up classification, though make it less precise. The parameter Complement, when true, indicates that the complement of the event behind the example has to be classified.

> `procedure Learn
> ( Classifier : in out Classifier_Object'Class;
> Lesson : Lecture_Handle;
> Features : Feature_Array;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Threshold : Confidence := Confidence'First;
> Equivalence : Confidence := Default_Equivalence;
> Viewer : not null access Indicator_Object'Class :=
> Negleter'Access
> );`

This procedure is a class-wide variant of Learn. It calls to the corresponding dispatching variant with the parameter Context constructed out of Lesson, a handle to the training set. The parameter Features specifies the sequence of features. The list may contain No_Feature elements, which are ignored. The sequence may be empty. The parameters From and To specify the range of training examples to learn from. Usually it is the whole set. The parameter To can be greater than the total number of examples. The parameter Threshold specifies the truncation level. All confidence factors below Threshold are treated as 0. The parameter Equivalence is the level of separation hypotheses quality. If the qualities differ less than Equivalence, they are assumed same. When Equivalence is Confidence'Last, features are not selected, so they order of testing is not changed, unless some features are undefined. The parameter Viewer specifies an indication object. The progress of is measured in percent.

> `function To_Classifier_Object_Ptr (Ptr : Deposit_Ptr)
> return Classifier_Object_Ptr;`

This function provides a downward access type conversion. Constraint_Error is propagated when Ptr does not point to a classifier.

> `function To_Confidence (X : Float) return Confidence;`

This converts a floating-point number to truth value. The values outside [0,1] are saturated to the corresponding margin.

> `function To_Deposit_Ptr is
> new Ada.Unchecked_Conversion
> ( Classifier_Object_Ptr,
> Deposit_Ptr
> );`

This function provides an upward access type conversion missing in Ada for pool-specific access types.

> `function Diff (Left, Right : Fuzzy_Boolean) return Divergence_Range;`

This function is the standard difference function use by default. It is evaluated as:

> Lower bound | = | min | (PLeft xor PRigh, NLeft xor NRight)
> Upper bound | = | max | (PLeft xor PRigh, NLeft xor NRight)

> `function Diff (Left, Right : Classification) return Divergence_Vector;`

This function apples Diff on per point basis.

> `procedure Verify
> ( Classifier : Classifier_Object'Class;
> Lesson : Lecture_Handle;
> Result : in out Lecture_Handle;
> Report : in out Intuitionistic.Set
> From : Positive := 1;
> To : Positive := Positive'Last;
> Threshold : Confidence := Confidence'First;
> Viewer : not null access Indicator_Object'Class := Negleter'Access;
> Difference : Divergence_Function := Diff'Access
> );
> procedure Verify
> ( Classifier : Classifier_Object'Class;
> Context : in out Classification_Parameters'Class;
> Result : in out Lecture_Handle;
> Report : in out Intuitionistic.Set
> From : Positive := 1;
> To : Positive := Positive'Last;
> Difference : Divergence_Function := Diff'Access
> );
> function Verify
> ( Classifier : Classifier_Object'Class;
> Lesson : Lecture_Handle;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Threshold : Confidence := Confidence'First;
> Viewer : not null access Indicator_Object'Class := Negleter'Access;
> Difference : Divergence_Function := Diff'Access
> ) return Intuitionistic.Set;
> function Verify
> ( Classifier : Classifier_Object'Class;
> Context : in out Classification_Parameters'Class;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Difference : Divergence_Function := Diff'Access
> ) return Intuitionistic.Set;`

These subprograms validate a classifier against examples from a fuzzy training set or a data context the training set is associated with. See Fuzzy.Classifier.Handle.Verify for further information.

Exceptions
Constraint_Error | Invalid classifier
Data_Error | I/O error when reading from the training set
End_Error | Operation was aborted by the indication object

> `Classifier_Class` `: constant String := "Classifier.";`

This string is used as the prefix in the names of objects classes for all classifiers.

#### 3.3.4. Graph-schemes

The package Fuzzy.Graph.Scheme implements classifiers based on graph-schemes. The package is a child of Fuzzy.Graph which provides nodes of fuzzy graphs. A graph-scheme consists of four fuzzy graphs deduced from four feature images.

> `type Root_Nodes_Array is array (Image_Type) of Node_Handle;
> type Graph_Scheme_Object is new Classifier_Object with record
> Roots : Root_Nodes_Array;
> Updated : Boolean := False;
> end record;`

Graph-scheme implements the interface of a classifier defined in the package Fuzzy.Classifier. Additionally it has the following operations of its own or defined on Classifier_Handle:

> `function Create
> ( Lesson : Lecture_Handle;
> Features : Feature_Array;
> Classes : Feature_Handle;
> From : Positive := 1;
> To : Positive := Positive'Last;
> Threshold : Confidence := Confidence'First;
> Equivalence : Confidence := Default_Equivalence;
> Viewer : not null access Indicator_Object'Class := Negleter'Access;
> Factory : not null access Node_Factory'Class :=
> Fuzzy.Graph.Memory_Resident.Factory
> ) return Classifier_Handle;
> function Create
> ( Context : access Graph_Training_Data'Class;
> Features : Feature_Array;
> From : Positive := 1;
> To : Positive := Positive'Last;
> ) return Classifier_Handle;
> `

These functions create a new graph-scheme by learning. The parameters are identical to ones of the procedures Learn (the primitive and class-wide ones) in Fuzzy.Classifier, except for the first parameter of the latter. Here a handle to the newly created graph-scheme is returned.

> `function Get_Graph
> ( Classifier : Classifier_Handle;
> Image : Image_Type
> ) return Node_Handle;
> function Get_Graph
> ( Classifier : Classifier_Object'Class;
> Image : Image_Type
> ) return Node_Handle;`

These functions return the root node of the graph deduced from the image specified by the parameter Image. The result can be an invalid handle. Constraint_Error is propagated if Classifier is not a valid handle or does not refer a graph-scheme. Carefully observe that when the handles returned should not be used to modify the graphs of the graph-scheme, then Set_Graph need to be called. Because any change made through a node handle does not influence the graph-scheme until Set_Graph is called.

> `function Get_Number_Of_Nodes (Classifier : Classifier_Handle)
> return Natural;
> function Get_Number_Of_Nodes (Classifier : Classifier_Object'Class)
> return Natural;`

These functions return the number of nodes in Classifier. A node counted different if there are many paths leading to it. Thus the number returned corresponds to a tree view on the graphs of the graph-scheme. Constraint_Error is propagated if Classifier is not a valid handle or does not refer a graph-scheme.

> `procedure Set_Graph
> ( Classifier : in out Classifier_Handle;
> Node : Node_Handle;
> Image : Image_Type
> );
> procedure Set_Graph
> ( Classifier : in out Classifier_Object'Class;
> Node : Node_Handle;
> Image : Image_Type
> );`

These procedures change a root node of the graph-scheme Classifier. The parameter Node is a handle to the root node of a graph. Image is the graph of Scheme to be set. Constraint_Error is propagated if the operation cannot be performed because the the new root node is incompatible with the graph-scheme.

> `Example_Image : constant array (Image_Type, Boolean) of
> Image_Type :=
> ( Has_In => (Has_In, Has_Not),
> Has_Not => (Has_Not, Has_In),
> Has_Out => (Has_Out, Has_Not_Out),
> Has_Not_Out => (Has_Not_Out, Has_Out)
> );`

When a graph of the scheme has to classify an example, the image from the training set to select is determined by the image of the graph (i.e. the images which the graph was trained on) and the type of the example (positive vs. negative). The array Example_Image encodes this mapping.

#### 3.3.5. Separating classifiers

The package Fuzzy.Classifier.Separator implements classifiers. The classifier implements the interface of a classifier defined in the package Fuzzy.Classifier. Additionally it has the following operations of its own or defined on Classifier_Handle:

> `function Create
> ( Classifier : Classifier_Handle;
> Separation : Confidence := Confidence'First;
> Completeness : Confidence := Confidence'Last
> ) return Classifier_Handle;`

This function creates a classifier that separates classes. It is built upon another classifier specified by the parameter Classifier. A separator classifier uses Classifier to classify classes known to be separate and complete to the levels specified to the parameters Separation and Completeness. Let C={cj | cj:Ω→[0,1]} be the set of fuzzy classes such that P(∩cj)≤a and N(∪cj)≥b. The parameter Separation is the confidence level of class separation. That is the possibility a of the intersection of the classes or else its estimation from above. The parameter Completeness is the confidence level of class completeness, i.e. the necessity b of the class union or its estimation from below. The built classifier uses the knowledge about the classes to refine the classifications given by the original classifier. Constraint_Error is propagated if Classifier is not a valid handle.

> `function Get_Classifier (Classifier : Classifier_Handle)
> return Classifier_Handle;`

This function returns a handle to the original classifier. Constraint_Error is propagated if Classifier is not a separating classifier created by Create or when Classifier is not a valid handle.

> `function Is_Separator (Classifier : Classifier_Handle)
> return Boolean;`

This function returns true if Classifier is a valid handle to a separating classifier. Constraint_Error is propagated if Classifier is an invalid handle.

#### 3.3.6. Identity classifiers

The package Fuzzy.Classifier.Identity implements identity classifiers. The classifier implements the interface of a classifier defined in the package Fuzzy.Classifier. Additionally it has the following operations of its own or defined on Classifier_Handle:

> `function Create (Classes : Feature_Handle)
> return Classifier_Handle;`

This function creates an identity classifier for the class-feature Classes. An identity classifier returns the value of the feature as it is specified in the training example to classify. Constraint_Error is propagated if Classes is not a valid handle.

> `function Is_Identity (Classifier : Classifier_Handle)
> return Boolean;`

This function returns true if Classifier a valid handle to an identity classifier. Constraint_Error is propagated if Classifier is an invalid handle.

### 3.4. Node objects

A graph node both represents itself as a node and as the trees rooted in it. Because operations on nodes influence the whole tree care must be taken to ensure consistency of all tree views. The operations defined on the node handles do it by replicating nodes if there is a possibility that the node can be viewed from elsewhere.

#### 3.4.1. Types

The package Fuzzy.Graph defines the type Graph_Node serving as the abstract base type for all node objects.

> `type Graph_Node (Cardinality : Positive) is
> abstract new Deposit with private;
> type Graph_Node_Ptr is access Graph_Node'Class;
> type Graph_Node_Ref is access constant Graph_Node'Class;`

The discriminant Cardinality defines the cardinality of the node, the cardinality of the feature it tests.

> `type Node_Ptr_Array is array (Integer range <>) of Graph_Node_Ptr;`

The type Node_Ptr_Array is the array of pointers to nodes.

> `type Node_Type is (Tree_Branch, Tree_Cluster, Tree_Leaf);`

The values type Node_Type are used to classify the node types. Leaf nodes are terminal nodes of the tree, they have no successors but determine an ultimate classification. Branch and Cluster nodes are ones with successors. They determine a partial, conditional classification. Root nodes are branches with no parents.

> `type Node_Modification is (Union, Intersection, Overriding);`

This enumeration type defines the types of the operations combining two nodes.

> `type Node_Factory is
> abstract new Ada.Finalization.Limited_Controlled with private;
> type Node_Factory_Ptr is access all Node_Factory'Class;`

A node factory object is used to create graph nodes. All operations creating new nodes use for this node factory object. This allows us to mix different implementations of nodes selected according to the factory used to create them.

> `type Node_Modification_Data is
> new Training_Data with
> record
> Factory : Node_Factory_Ptr;
> end record;`

A node modification data context is used in all operations where a graph node is modified. The type is derived from training data context. It has an additional field Factory which determines the node factory. Note that some operations may change the current node factory.

#### 3.4.2. Primitive operations on nodes

The following are the primitive operations of the type Graph_Node. They are abstract and have to be implemented in derived types.

> `procedure Classify
> ( Node : Graph_Node;
> Data : in out Classification_Parameters'Class;
> Weight : Confidence := Confidence'Last
> ) is abstract;`

This procedure uses the graph rooted in Node to classify one example from a fuzzy training set. The parameter Data specifies the classification parameters. The parameter Weight is the confidence in the path leading to the node. Any node has to implement this procedure. Branch nodes usually call it recursively on their successors. The result is accumulated in Data. Constraint_Error is propagated when Node or Data is invalid.

> `procedure Finalize (Node : in out Graph_Node);`

The procedure checks that the finalized node is detached from any graph.

> `function Find
> ( Node : Graph_Node;
> Feature : Feature_Object'Class
> ) return Graph_Node_Ptr is abstract;`

This function is used to find any node testing Feature and belonging to the same graph as Node. The result is null if Node does not belong to any graph or is not tested by the graph.

> `function Get_Child
> ( Node : Graph_Node;
> Index : Positive
> ) return Graph_Node_Ptr is abstract;`

This function returns the child node associated with the feature domain point specified by Index. Note that same child may be associated with more than one domain point of the tested feature. The result is null if Index is not in range, Node is not in a graph, or there is no child node satisfying the condition.

> `function Get_Children_Number
> ( Node : Graph_Node;
> Immediate : Boolean := True
> ) return Natural is abstract;`

This abstract function returns the number of successor nodes. Only immediate successors are counted when Immediate is true.

> `function Get_Classes (Node : Graph_Node;
> return Feature_Object_Ptr is abstract;`

Each graph has a dedicated feature describing the set of classes (class-feature). This function returns the feature. Constraint_Error is propagated Node belongs to no graph.

> `function Get_Distribution (Node : Graph_Node)
> return Classification is abstract;`

The result is a fuzzy classification of the feature tested by the node. For a leaf node it is a classification given by the node. For other nodes it is the weights of the arcs leading out of the node.

> `procedure Get_Examples
> ( Node : Graph_Node;
> Lesson : in out Lecture_Handle;
> Viewer : not null access Indicator_Object'Class :=
> Negleter'Access
> ) is abstract;`

This abstract procedure extracts training examples from the graph rooted in Node. Each graph has a corresponding training set which exhaustively describes it. The extracted examples are added to the training set specified by the handle Lesson. The parameter Image determines which feature images have to be defined by the extracted examples. Though it has no effect on the class-feature, of which classifications (has-in, has-not) are defined. The parameter Viewer specifies an indication object. The implementation should recursively go through the successor nodes. The progress of is measured in percent.

Exceptions
Constraint_Error | Node belongs to no graph
Data_Error | I/O error when writing into the training set
End_Error | Operation was aborted by the indication object

> `function Get_Factory (Node : Graph_Node)
> return Node_Factory_Ptr is abstract;`

This function returns the node factory which can be used to create nodes compatible with the given one.

> `function Get_Feature (Node : Graph_Node)
> return Feature_Object_Ptr is abstract;`

This function returns the handle of the feature tested by Node. Constraint_Error is propagated when Node belongs to no graph.

> `function Get_Feature (Node : Graph_Node; Index : Positive)
> return Feature_Object_Ptr is abstract;`

The parameter Node can specify any node of the graph. The parameter Index should be in the range 1..Get_Features_Number. Constraint_Error is propagated when Node belongs to no graph or there is not such feature for the index specified.

> `function Get_Features_Number (Node : Graph_Node)
> return Natural is abstract;`

This function returns the number of the features tested by the graph containing Node. This set contains the class-feature. Zero is the result if Node belongs to no graph.

> `function Get_Sibling (Node : Graph_Node; Index : Positive)
> return Graph_Node_Ptr is abstract;`

This function provides a way to enumerate nodes of a graph layer. A layer consists of the nodes testing the same feature. The parameter Node identifies one node of the layer. The parameter Index indicates the number of a node in the layer. All nodes of a layer are enumerated from 1 to Get_Siblings_Number. Note that a node is a sibling of itself. Constraint_Error is propagated when Node belongs to no graph or Index specify no node.

> `function Get_Siblings_Number (Node : Graph_Node)
> return Natural is abstract;`

This function returns the number of nodes in a graph layer. A layer consists of the nodes testing the same feature. The parameter Node identifies any node of the layer. The result is zero when Node belongs to no graph.

> `function Get_Type (Node : Graph_Node) return Node_Type is abstract;`

This abstract function returns the type of Node.

> `procedure Initialize (Node : in out Graph_Node);`

This is the node construction procedure.

> `procedure Modify
> ( Parent : in out Graph_Node;
> Data : in out Node_Modification_Data'Class;
> Children : Node_Ptr_Array;
> Exclusive : Boolean;
> Combination : Node_Modification;
> New_Node : in out Graph_Node_Ptr
> ) is abstract;`

This procedure is used to modify a branch node. The parameter Parent is the node to be modified. When the result of the operation should change it, then the parameter Exclusive determines whether a new node should be created. When Exclusive is true Modify is allowed to apply changes to Parent. In both cases the result is checked for being equivalent to some already existing node, which is used then. New_Node points to the result if and only if it differs from Parent, otherwise New_Node is not changed. To determine if New_Node refers to a newly created node, rather than a reused one, New_Node.Use_Count should be tested for zero. The parameter Children is an array of pointers to the successors of Parent. It can contain null-elements. The number of elements in Children should be the cardinality of the feature tested by the node. Otherwise, Constraint_Error is propagated. It is also propagated if Children contains nodes belonging to a graph other than one of Parent, or when Parent is of no graph. The result successors of Parent are determined according to the parameter Combination of Node_Modification type:

- Union: the node will have a successor specified in Children or if it is absent then one of the node;
- Intersection takes the successor node from Children only if there already is a child;
- Overriding replaces everything with Children.

Note that an implementation need not test if any of children is an ancestor of Parent preventing circular dependencies. It is caller's responsibility to ensure this.

> `procedure Modify
> ( Leaf : in out Graph_Node;
> Data : in out Node_Modification_Data'Class;
> Distribution : Classification;
> Exclusive : Boolean;
> Combination : Node_Modification;
> New_Node : in out Graph_Node_Ptr
> ) is abstract;`

This procedure is used to modify a leaf node. The parameter Leaf is the node to be modified. When the result of the operation should change it, then the parameter Exclusive determines whether a new node should be created. When Exclusive is true Modify is allowed to apply changes to Leaf. In both cases the result is checked for being equivalent to some already existing node, which is used then. New_Node points to the result if and only if it differs from Leaf, otherwise New_Node is not changed. To determine if New_Node refers to a newly created node, rather than a reused one, New_Node.Use_Count should be tested for zero. The parameter Distribution specifies the expected classification of the example from Data. It is a combination of the current example classification and the weight (conditional possibility) evaluated by the parent nodes. The parameter Combination specifies how Distribution is combined with the classification delivered by the node. The parameter Data determines the training context. When the node encapsulates some classifier the latter can be trained on these data. Otherwise the parameter is ignored. Modify is allowed to pass Use_Error to the caller if the indication object of Data raises it.

> `function Tests
> ( Node : Graph_Node;
> Feature : Feature_Handle
> ) return Boolean is abstract;`

This abstract function is used to check whether a graph Node belongs to, tests Feature. I.e. if at least one node of the graph-scheme does it.

#### 3.4.3. Primitive operations on factories

The following operations define the interface of an abstract node factory:

> `function Create
> ( Factory : not null access Node_Factory;
> Feature : Feature_Object'Class;
> Children : Node_Ptr_Array;
> Weights : Set
> ) return Graph_Node_Ptr is abstract;
> function Create
> ( Factory : not null access Node_Factory;
> Feature : Feature_Object'Class;
> Children : Node_Ptr_Array
> ) return Graph_Node_Ptr is abstract;`

These function create a branch node which may have children. The parameter Factory is the factory used to create the node. Note that the factory returned by Get_Factory applied to the created node should not necessarily be exactly the one specified by the parameter Factory. The parameter Feature is the feature tested by the node. The parameter Children is the array of successors which for each domain point value of the feature contains either null or a pointer to some child node. The parameter Weights is a fuzzy set over feature domain. For each feature domain value it has the possibility that the node should have an arc leading to the corresponding successor node specified in Children. When Weights is omitted, it is assumed crisp having 1 (true) for each non-null element of Children and 0 otherwise. Constraint_Error is propagated if the resulting node would have no successors or when any of the successors belong to no or different graphs. It also propagates when cardinalities of Children or Weights don't match one of the Feature. An implementation is also allowed to raise End_Error.

> `function Create
> ( Factory : not null access Node_Factory;
> Classes : Feature_Object'Class;
> Distribution : Classification
> ) return Graph_Node_Ptr is abstract;`

This function creates a leaf node. As above the parameter Factory is the factory used to create the node and it can be different from the result of Get_Factory returned by the newly created node. The classification given by the returned node should be Distribution. The parameter Classes is a pointer to the class-feature. Constraint_Error is propagated when Distribution has cardinality different from the class-feature. An implementation is also allowed to raise End_Error.

#### 3.4.4. Other operations on nodes

> `function Get_Number_Of_Nodes return Natural;`

This function returns the total number of all existing nodes.

> `function Like
> ( Left : Graph_Node'Class;
> Right : Graph_Node'Class
> ) return Boolean;`

This function compares nodes. Two nodes are equivalent if they give equivalent classifications of same training sets. Leaf nodes precede branch nodes. Nodes of lesser cardinality precede the nodes of greater one. Leaf nodes are compared by their classifications. Branches comparison is shallow. i.e. if the nodes involved are branches, then their children can be compared as objects (by memory addresses). This function is used in graph layers to factor out similar nodes. Because comparison is shallow the children nodes have to be factored out before the parent ones. See also Precedent.

> `function Precedent
> ( Left : Graph_Node'Class;
> Right : Graph_Node'Class;
> ) return Boolean;`

This function compares nodes. Two nodes are equivalent if they give equivalent classifications of same training sets. The comparison implemented by this function is shallow. Precedent and Like are used for factoring out similar nodes and thus improve training performance.

> `function To_Graph_Node_Ptr (Ptr : Deposit_Ptr)
> return Graph_Node_Ptr;`

This function provides a downward access type conversion. Constraint_Error is propagated when Ptr does not point to a graph node.

> `function To_Deposit_Ptr is
> new Ada.Unchecked_Conversion
> ( Graph_Node_Ptr,
> Deposit_Ptr
> );`

This function provides an upward access type conversion missing in Ada for pool-specific access types.

> `Graph_Class : constant String := "Graph-scheme.";
> Node_Class : constant String := Graph_Class & "Node.";`

These strings are used as prefixes in the names of objects classes for all nodes and graph-schemes.

#### 3.4.5. Training nodes

The package Fuzzy.Graph.Handle.Learning provides data types used for training graphs.

> `type Graph_Training_Data
> ( Lesson : not null access Lecture_Object'Class;
> Length : Natural;
> Cardinality : Positive;
> Viewer : not null access Indicator_Object'Class
> ) is new Node_Modification_Data (Lesson, Length, Viewer) with
> record
> Selected : Feature_Handle;
> Class_Cut : Confidence;
> Example_Cut : Confidence;
> Pro : Boolean;
> Features : Features_Lists.Set;
> Classes : Feature_Handle;
> Statistics : Feature_Statistics_Maps.Map;
> Depth : Natural := 0;
> Rotations : Natural := 0;
> Cache : aliased Separation_Hypotheses_Cache (Cardinality);
> end record;`

This structure is used during training of graphs too keep training data and parameters The meaning of its distriminants and fields:

- Cache is the features separation hypotheses cache;
- Cardinality is one of the class-feature;
- Classes is a handle to the class-feature.
- Class_Cut is the the possibility of the current class or the possibility of the current class complement (see Pro). This field is ignored when not learning from has-out or has-not-out;
- Depth is the depth of the current node being modified. The root node has the depth 0. This field is changed during training as the graph is navigated;
- Example_Cut is an estimation of Nr|r, the necessity of the current example under the condition of itself. Here r is the current example. This field is ignored when not learning from has-out or has-not-out;
- Features are ones the graph will possibly test. Usually this is the set of the features used in the training set;
- Lesson is the training set;
- Pro is true, when the field Class_Cut is the possibility of the current class. It is false when Class_Cut is the possibility of the complement of the current class. This field is ignored when training from has-in or has-out;
- Rotations is the total number of rotations made during training;
- Selected is a handle to the feature selected for training. All other features are assumed to have images all 1. This field is ignored when training from has-in and has-out images;
- Statistics is the statistics gathered about features;
- Viewer is a pointer to an indication object.

### 3.5. Indicator objects

The package Indicators provides the base type for progress indication objects:

> `type Indicator_Object is
> new Object.Entity with null record;
> type Indicator_Object_Ptr is access Indicator_Object'Class;
> type Indicator_Object_Ref is access constant Indicator_Object'Class;`

An instance of Indicator_Object'Class is passed to all potentially lengthy operations to indicate their progress or abort the operation. An operation is initiated by Reset and is finished by Done. In between its progress is indicated by calls to Check. An implementation of Indicator can override these operations to provide corresponding visual effects and allow the operator to influence operation progress. It can raise End_Error which will abort the operation and propagate out of the subroutine implementing it.

> `type Indicator_Data is abstract
> new Ada.Finalization.Limited_Controlled with null record;`

This is the abstract base for subprogram-specific parameters. Some subprograms using indicators may call Set_Data to pass additional parameters to the indicator at hand. The parameters to pass should be packed into a type derived from this base.

> `procedure Check (Viewer : in out Indicator);`

This procedure is called to indicate an operation progress. The parameter Viewer is the indicator object specified in the operation call. An implementation may raise End_Error to abort the pending operation. In this case End_Error will propagate out of the operation.

> `procedure Done (Viewer : in out Indicator);`

This procedure is called to indicate a successful operation completion. If an sub-operation is pending, Done ends the it, which corresponds to one check point of the parent operation, i.e. to one call to Check. An implementation may raise End_Error to abort the pending operation.

> `procedure Reset (Viewer : in out Indicator; Total : Natural := 0);`

A consequent call to Reset indicates a suboperation which to be ended by Done. As a whole it corresponds to one check point of the current operation. There can be an unlimited number of nested operation levels. The parameter Total specifies the number of check points or steps of the suboperation. Zero is specified when the total number of steps is unknown, like when a source file is read and the number of lines to expect is unknown. Usually it has no sense for a suboperation.

> `procedure Set_Data
> ( Viewer : in out Indicator_Object;
> Data : in out Indicator_Data'Class
> );
> procedure Set_Data (Viewer : in out Indicator_Object);`

This procedure can be used to make the indicator aware of some additional parameters. A program dealing with an indicator may use Set_Data to communicate with the indicator. The indicator can always ignore this call. The default implementation does nothing. An implementation may raise End_Error to abort the pending operation. The variant without the second parameter is used to remove the effect of setting any parameters. Normally, if an indicator type overrides one Set_Data, it also does another.

> `Negleter : aliased Indicator;`

This object is used as a default for an indication object. It ignores everything.

#### 3.5.1. Indicators based on text I/O

The package Indicator.Text_IO provides various progress indicators based on text I/O for output devices supporting backspace.

> `type Progress is abstract new Indicator with private;`

This type serves as the abstract base for all text I/O progress Indicator. It has the abstract operation to override:

> `function Get_Text (Viewer : Progress) return String
> is abstract;`

The derived type have to implement this function.

> `type Bar (Size : Positive) is new Progress with private;`

This indicator shows the operation progress is shown in the form:

> `|HHHHHHHHHI | 60.05%`

The type discriminant Size specifies the size of the bar, i.e. the number of characters `'H'`, shown when the progress is 100%.

> `type Counter (Suffix : access String) is new Progress with private;`

This indicator shows the operation progress as a plain number followed by the text in the discriminant Suffix: for example, when Suffix points to `" lines read"` then the progress will be indicated as:

> `123 lines read`

> `type Timed_Bar is new Bar with private;`

This indicator shows the operation progress is shown in the form:

> `|HHHHHHHHHI | 60.05% +10s`

The discriminant Size specifies the size of the bar, i.e. the number of characters `'H'`, shown when the progress is 100%. Additionally this indicator shows the estimated time for the operation to complete.

### 3.6. Defuzzifier objects

A defuzzifier object represents a defuzzification method applied to a linguistic variable in order to obtain its crisp numerical equivalent in some application determined way. Defuzzifiers depend on the corresponding linguistic features they have to work with. For this reason the packages defining defuzzifier objects types are made child packages of Fuzzy.Feature.Generic_Domain_Float.Generic_Linguistic.

#### 3.6.1. Generic defuzzifiers

The generic child package Fuzzy.Feature.Generic_Domain_Float.Generic_Defuzzifier is used to create defuzzifier types:

> `generic
> package Fuzzy.Feature.Generic_Domain_Float.Generic_Defuzzifier is ...`

The package declares the type Defuzzifier_Object serving as the base type for all implementation-specific defuzzifier types:

> `type Defuzzifier_Object is abstract new Deposit with null record;
> type Defuzzifier_Object_Ptr is access Defuzzifier_Object'Class;`

The following operation is abstract and have to be defined by the derived type:

> `function` `Defuzzify
> ( Defuzzifier : Defuzzifier_Object;
> Value : Variable_Measure
> ) return Measure is abstract;`

An implementation of this function should return a defuzzified value of the linguistic variable Value. When defuzzification is impossible it may raise Constraint_Error.

> `function` `To_Defuzzifier_Object_Ptr (Ptr : Deposit_Ptr)
> return Defuzzifier_Object_Ptr;`

This function provides a downward access type conversion. Constraint_Error is propagated when Ptr does not point to a graph node.

> `function To_Deposit_Ptr is
> new Ada.Unchecked_Conversion
> ( Defuzzifier_Object_Ptr,
> Deposit_Ptr
> );`

This function provides an upward access type conversion missing in Ada for pool-specific access types.

> `Defuzzifier_Class : constant String := "Defuzzifier." & Suffix``;`

This string is used as a prefix in the names of objects classes for all defuzzifiers.

#### 3.6.2. Generic handles to defuzzifiers

The generic child package Fuzzy.Feature.Generic_Domain_Float.Generic_Defuzzifier.Generic_Handle is provides handles to defuzzifier objects, which base type is declared in the parent package.

> `generic
> package Fuzzy.Feature.Generic_Domain_Float.Generic_Defuzzifier.
> Generic_Handle is ...`

The package declares the type Defuzzifier_Handle used to access all defuzzifier objects derived from Defuzzifier_Object. The operations are defined on Defuzzifier_Handle were described before.

#### 3.6.3. Generic factory of defuzzifiers

The child generic package Fuzzy.Feature.Generic_Domain_Float.Generic_Defuzzifier.Generic_Handle.Generic_Method is can be used for creating a defuzzifier factory from a defuzzification function:

> `generic
> Name : String;
> with function Method (Value : Variable) return Domain_Number;
> package Fuzzy.Feature.Generic_Domain_Float.Generic_Defuzzifier.
> Generic_Handle.Generic_Method is ...`

The parameter Name is the name of the method. It will be uses as a suffix of the defuzzifier object classe registered by the factory. The generic parameter Method is the function which implements defuzzification. It should either defuzzify the argument or raise Constraint_Error.

The package provides the factory function

> `function Create return Defuzzifier_Handle;`

which serves as a factory.

## 4. Examples

The sample programs illustrating use of the software are located in the subdirectory examples.

### 4.1. Example 1. Creation of a training set

This example illustrates manual creation of training sets and HTML output. The program creates a training set and two features. Then it places two examples into the training set. After that it puts the training set into the file example1.htm in the HTML format:

File example1.adb:

`with Ada.Text_IO; use Ada.Text_IO; with Fuzzy.Feature.Domain_Floats; use Fuzzy.Feature.Domain_Floats; with Fuzzy.Feature.Float_Handle; use Fuzzy.Feature.Float_Handle; with Fuzzy.Feature.Handle; use Fuzzy.Feature.Handle; with Fuzzy.Feature.Handle.Edit; use Fuzzy.Feature.Handle.Edit; with Fuzzy.Feature.Handle.Factory; use Fuzzy.Feature.Handle.Factory; with Fuzzy.Lecture.Handle; use Fuzzy.Lecture.Handle; with Fuzzy.Lecture.Handle.HTML; use Fuzzy.Lecture.Handle.HTML; with Fuzzy.Floats.Edit; -- I/O for fuzzy numbers with Fuzzy.Feature.Domain_Float_Handle; procedure Example1 is package Fuzzy_Edit is new Fuzzy_Floats.Edit (Float_Edit); use Fuzzy_Edit; use Fuzzy_Measures; use Fuzzy.Feature.Domain_Float_Handle; use Irregular_Measures; File : File_Type; Lesson : Lecture_Handle; Color : Feature_Handle := Create_Discrete ("Color", "Red, Green, Blue"); Height : Feature_Handle := Create_Float ("Height", 10, 120.0, 200.0, "foot"); begin -- -- Create an output file -- Create (File, Out_File, "example1.htm"); -- -- Set the first example, for the feature color. The value is -- specified as a string which is converted to a classification using -- Fuzzy.Feature.Handle.Edit.Value. -- Put (Lesson, 1, Color, Value ("Red:1:1, Green:0.5:0.2", Color)); -- -- Set the first example, for the feature height. The value of the -- feature is converted from a string to a fuzzy float and then to a -- classification of the feature. -- Put ( Lesson, 1, Height, Classify ( Height, Value ("152..180:0.2,159..175:0.5,165..170:0.8, 166..167:1")*ft ) ); -- -- Set the second example, for the feature height. Here we again use -- Value from Fuzzy.Feature.Handle.Edit. -- Put (Lesson, 2, Height, Value ("47..50m:1:1", Height)); -- -- Write the training set into the file -- Put (File, Lesson); -- -- Close the file -- Close (File); end Example1;`

To create a training set one usually would use the package Fuzzy.Lecture.Handle.Factory to specify the training set type. But in this example the set is created implicitly by putting examples there.

The procedure Put defines feature value for given example. The function Classify converts a dimensioned fuzzy number to fuzzy classification. The function Value from Fuzzy.Feature.Handle.Edit creates a fuzzy floating-point value from a string. The result is then multiplied by ft (foot). For the second example of the training set the value of the feature Height is obtained using Fuzzy.Feature.Handle.Edit.Value with the string `47..50m:1:1`. Note how a unit different from one of the feature is used. The file example1.htm created by this program looks like:

No. | Color | Height [foot]
1 |
Red | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Green | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Blue | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[120.0000, 128.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[128.0000, 136.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[136.0000, 144.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[144.0000, 152.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[152.0000, 160.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[160.0000, 168.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[168.0000, 176.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[176.0000, 184.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[184.0000, 192.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[192.0000, 200.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
2 |
Red | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Green | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Blue | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[120.0000, 128.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[128.0000, 136.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[136.0000, 144.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[144.0000, 152.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[152.0000, 160.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[160.0000, 168.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[168.0000, 176.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[176.0000, 184.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[184.0000, 192.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
[192.0000, 200.0000] | ||||||||||||||||||||||||||||||||||||||||||||||||||||

Each row of the table corresponds to an example. The first column contains the number of the example. Other columns represent the fuzzy classifications of the training example by the corresponding features. Note that the second example has no defined classification for the feature Color. Therefore it is unknown, i.e. all values are possible and neither is necessary.

### 4.2. Example 2. Manual creation of a graph

This example demonstrates manual creation of a graph and HTML output. The program creates a graph classifying animals. It defines the features Covering with the domain {Feather, Fur, Scale, None} and Limbs with the domain {Legs, Wings, Fins}. It also defines the class-feature Creature with the domain {Fish, Reptile, Bird, Human, Seal, Beast}. The graph-scheme is built node by node using the functions of the package Fuzzy.Feature.Handle.Manual. After that it is put into the file example2.htm in HTML format. For this the procedures of Fuzzy.Graph.Handle.HTML are used. The built graph is also applied to perform a simple classification:

File example2.adb:

`with Ada.Text_IO; use Ada.Text_IO; with Fuzzy.Feature.Handle; use Fuzzy.Feature.Handle; with Fuzzy.Feature.Handle.Edit; use Fuzzy.Feature.Handle.Edit; with Fuzzy.Feature.Handle.Factory; use Fuzzy.Feature.Handle.Factory; with Fuzzy.Feature.Handle.HTML; use Fuzzy.Feature.Handle.HTML; with Fuzzy.Graph.Handle; use Fuzzy.Graph.Handle; with Fuzzy.Graph.Handle.HTML; use Fuzzy.Graph.Handle.HTML; with Fuzzy.Graph.Handle.Manual; use Fuzzy.Graph.Handle.Manual; with Fuzzy.Lecture.Handle; use Fuzzy.Lecture.Handle; procedure Example2 is File : File_Type; Covering, Limbs, Creature : Feature_Handle; Graph : Node_Handle; begin Covering := Create_Discrete ("Covering", "Feather, Fur, Scale, None"); Limbs := Create_Discrete ("Limbs", "Legs, Wings, Fins"); Creature := Create_Discrete ( "Creature", "Fish, Reptile, Bird, Human, Seal, Beast" ); -- -- Create the output file -- Create (File, Out_File, "Example2.htm"); declare Has_Feather, Has_Fur, Has_Scale, Has_None : Node_Handle; Bird, Beast, Seal, Reptile, Fish, Human : Node_Handle; begin -- -- Create leaf nodes -- Bird := Create_Leaf (Creature, Value ("Bird:1:1", Creature)); Beast := Create_Leaf (Creature, Value ("Beast:1:1", Creature), Bird); Seal := Create_Leaf (Creature, Value ("Seal:1:1", Creature), Bird); Reptile := Create_Leaf (Creature, Value ("Reptile:1:1", Creature), Bird); Fish := Create_Leaf (Creature, Value ("Fish:1:1", Creature), Bird); Human := Create_Leaf (Creature, Value ("Human:1:1", Creature), Bird); -- -- Create nodes testing limbs -- Has_Feather := Create_Branch (Limbs, (Bird, Bird, No_Node)); Has_Fur := Create_Branch (Limbs, (Beast, Beast, Seal)); Has_Scale := Create_Branch (Limbs, (Reptile, No_Node, Fish)); Has_None := Create_Branch (Limbs, (Human, No_Node, No_Node)); -- -- Create the root node testing the feature Covering -- Graph := Create_Branch ( Covering, (Has_Feather, Has_Fur, Has_Scale, Has_None) ); end; -- -- Write the built graph into the file -- Put_Line (File, "The built graph:"); Put (File, Graph); -- -- Let's see how the graph classifies -- declare Something : Lecture_Handle; begin -- -- Define the feature Limbs in the example 1 -- Put ( Something, 1, Limbs, Value ("Legs:1:1", Limbs) ); -- -- Define the feature Covering in the example 1 -- Put ( Something, 1, Covering, Value ("Fur, Feather:0.8, Scale:0.5", Covering) ); Put_Line (File, "The result of classification:"); -- -- Classify the example 1 and write the result into the file -- Put ( File, Creature, Classify (Graph, Something, 1, Fuzzy.Feature.Has_In) ); end; -- -- Close the file -- Close (File); end Example2;`

Leaves are created using the function Value. It converts a text string into a classification, which the leaf will provide. When the first leaf node (Bird) is created, this automatically creates the graph. All following leaves are created with the first leaf specified as a parameter. This ensures that all leaves will be in the same graph. The graph branches testing the feature Limbs are created by specifying leaves as their descendants. Finally, the root node is created to test the feature Covering. The graph output in the file example2.htm looks as follows:

Covering in Feather |
Limbs in Legs..Wings | Creature
Fish | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Reptile | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Bird | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Human | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Seal | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Beast | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Covering in Fur |
Limbs in Legs..Wings | Creature
Fish | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Reptile | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Bird | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Human | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Seal | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Beast | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Limbs in Fins | Creature
Fish | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Reptile | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Bird | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Human | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Seal | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Beast | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Covering in Scale |
Limbs in Legs | Creature
Fish | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Reptile | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Bird | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Human | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Seal | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Beast | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Limbs in Fins | Creature
Fish | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Reptile | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Bird | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Human | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Seal | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Beast | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Covering in None |
Limbs in Legs | Creature
Fish | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Reptile | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Bird | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Human | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Seal | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Beast | ||||||||||||||||||||||||||||||||||||||||||||||||||||

Each row of the table corresponds to an arc and consists of two cells. The first cell contains the range of the feature values for which there is an arc to follow. The second cell contains the graph-scheme the arc leads to. For instance, the built graph has a path

> Covering⊆Scale→Limbs⊆Fins→Creature=Fish

Note that all arcs of the graph are crisp, because the whole fuzziness is accumulated in the leaf nodes.

The program example2 also classifies an example using this graph. Let we saw a creature for a tiny moment of time. It definitely had legs, but we are not sure about its covering. Possibly it was fur (1:0), maybe feather (0.8:0) or scale (0.5:0). The result of classification of the has-in image is shown below:

Fish | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Reptile | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Bird | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Human | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Seal | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Beast | ||||||||||||||||||||||||||||||||||||||||||||||||||||

Observe that Beast is not just fully possible, but also necessary to the level of not Bird, which is the second possible outcome. Other images are useless to classify, because the training set did not define them.

### 4.3. Example 3. Learning from a training set

This example demonstrates learning from a training set and using text input of training sets:

File example3.adb:

`with Ada.Text_IO; use Ada.Text_IO; with Confidence_Factors; use Confidence_Factors; with Fuzzy.Classifier.Handle; use Fuzzy.Classifier.Handle; with Fuzzy.Feature.Handle; use Fuzzy.Feature.Handle; with Fuzzy.Feature.Handle.Factory; use Fuzzy.Feature.Handle.Factory; with Fuzzy.Lecture.Handle; use Fuzzy.Lecture.Handle; with Fuzzy.Lecture.Handle.HTML; use Fuzzy.Lecture.Handle.HTML; with Fuzzy.Lecture.Handle.Text_IO; use Fuzzy.Lecture.Handle.Text_IO; with Fuzzy.Classifier.Handle.Factory; use Fuzzy.Classifier.Handle.Factory; procedure Example3 is File : File_Type; Lesson : Lecture_Handle; X : Feature_Handle := Create_Integer ("X", 1, 7); Y : Feature_Handle := Create_Integer ("Y", 1, 7); Class : Feature_Handle := Create_Discrete ("Class", "First, Second"); procedure Report (Scheme : Classifier_Handle) is separate; begin -- -- Create an output file -- Create (File, Out_File, "Example3.htm"); -- -- Read a training set from a file -- Lesson := Read ("example3.txt", (X, Y, Class)); -- -- Write the training set into the output file -- Put_Line (File, "The training set:"); Put (File, Lesson); -- -- Learn using X and Y -- Report ( Learn ( Lesson, (X, Y), Class, Equivalence => Confidence'Last ) ); -- -- Close the file -- Close (File); end Example3;`

Here, first the features X, Y and Class are created. Then a training set Lesson is created and read from the file example3.txt. The training set is put in the output HTML file. After that a classifier is trained on the set. Learning is performed without features selection because selection would make the feature Y leading. This would produce a more dense graph, but worse performing one. The parameter Equivalence set to Confidence'Last forbids features selection. Finally, the procedure Report is used to analyze a built graph-scheme:

File example3-report.adb contains the separate body of the procedure Report:

`with Confidence_Factors.Edit; use Confidence_Factors.Edit; with Fuzzy.Classifier.Handle.HTML; use Fuzzy.Classifier.Handle.HTML; with Fuzzy.Feature.Handle.Edit; use Fuzzy.Feature.Handle.Edit; with Integer_Intervals; use Integer_Intervals; with HTML; use HTML; separate (Example3) procedure Report (Scheme : Classifier_Handle) is Test : Lecture_Handle; Example : Integer := 0; begin Put_Line (File, "<p>The result of training</p>"); -- -- Write the result of learning into the file -- Put (File, Scheme); -- -- Let's see how it classifies the singletons -- for X_Index in 1..Get_Cardinality (X) loop for Y_Index in 1..Get_Cardinality (Y) loop Example := Example + 1; Put (Test, Example, X, Value (Integer'Image (X_Index), X)); Put (Test, Example, Y, Value (Integer'Image (Y_Index), Y)); Put (Test, Example, Class, Classify (Scheme, Test, Example)); end loop; end loop; -- -- Images of the classes: -- for Class_No in 1..Get_Cardinality (Class) loop Put_Line ( File, ( Break & "Image of " & Image ( Class, Interval'(Class_No, Class_No) ) ) ); Example := 1; for X_Index in 1..Get_Cardinality (X) loop Put_Line (File, Break); for Y_Index in 1..Get_Cardinality (Y) loop Put_Line ( File, Image ( Classify ( Scheme, Test, Example ) .Possibility (Class_No) ) ); Example := Example + 1; end loop; end loop; end loop; end Report;`

The features X and Y are integer features with the ranges 1..7. The feature Class is a discrete feature over the domain set {First, Second}. It serves as the class-feature. The images of the classes First and Second in the pattern space are:

Here the image of the class First is shown on the left in ochre, the image of Second is on the right in cyan. Though it looks easy for a human being to separate these two classes it would be a very difficult case for classification methods using linear separating surfaces or set to set distances. The training set is read from the file example3.txt. It is not representative because it covers only a part of the pattern space, the points of the pattern space defined by the training set are highlighted by darker colors on the picture above. The file is:

File example3.txt:

`-- -- X Y Classes --------------------------------- 1:1:0, 7:1:0 1:1:0, 7:1:0 First 1..7:1:0 1:1:0, 7:1:0 First <*> 2 3 First:0.6, Second:0.3 <*> 3 3 First:0.3, Second:0.6 <*> 4 4 Second <*> 5 5 First:0.3, Second:0.6 <*> 6 5 First:0.6, Second:0.3`

For reading the training set from the file, the package Fuzzy.Lecture.Text_IO is used. After that a graph-scheme that uses the features X and Y is built from the set. It classifies the points of the pattern space as shown on the following picture:

As we see it is pretty close to the original images of the classes. The graph-scheme built:

Deduced from HAS_IN images
X in 1, 7 |
Y in 1, 7 | Class
First | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Second | ||||||||||||||||||||||||||||||||||||||||||||||||||||
X in 2 |
Y in 1, 7 | Class
First | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Second | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Y in 3 | Class
First | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Second | ||||||||||||||||||||||||||||||||||||||||||||||||||||
X in 3 |
Y in 1, 7 | Class
First | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Second | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Y in 3 | Class
First | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Second | ||||||||||||||||||||||||||||||||||||||||||||||||||||
X in 4 |
Y in 1, 7 | Class
First | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Second | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Y in 4 | Class
First | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Second | ||||||||||||||||||||||||||||||||||||||||||||||||||||
X in 5 |
Y in 1, 7 | Class
First | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Second | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Y in 5 | Class
First | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Second | ||||||||||||||||||||||||||||||||||||||||||||||||||||
X in 6 |
Y in 1, 7 | Class
First | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Second | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Y in 5 | Class
First | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Second | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|  | Deduced from HAS_OUT images:
X in 1..7 |
Y in 1..7 | Class
First | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Second | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Deduced from HAS_NOT images:
X in 1..3, 5..7 |
Y in 1..7 | Class
First | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Second | ||||||||||||||||||||||||||||||||||||||||||||||||||||
X in 4 |
Y in 1..3, 5..7 | Class
First | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Second | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Y in 4 | Class
First | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Second | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Deduced from HAS_NOT_OUT images:
X in 1..7 |
Y in 1..7 | Class
First | ||||||||||||||||||||||||||||||||||||||||||||||||||||
Second | ||||||||||||||||||||||||||||||||||||||||||||||||||||

### 4.4. Example 4. Working with a data base

This example shows how to use a data base to store and restore features, training sets. The data to classify are taken from the UCI Repository of machine learning databases [http://archive.ics.uci.edu/ml/]. Irvine, CA: University of California, Department of Information and Computer Science:

> Name : |  | Postoperative Patient Data
> Creators : |  | Sharon Summers, School of Nursing, University of Kansas Medical Center, Kansas City, KS 66160 Linda Woolery, School of Nursing, University of Missouri, Columbia, MO 65211
> Donor: |  | Jerzy W. Grzymala-Busse (jerzy@cs.ukans.edu) (913)864-4488
> Date: |  | June 1993

The method LERS (LEM2) originally used with these data was reported to have 48% accuracy.

The sample program first creates the necessary features and reads the training data from the file example4.txt. The 2/3 of the training set is used for learning. The rest is classified to compare the work of the classifier built with the classification provided by the set. For illustrative purpose the process is split in three sessions. Each session establishes a connection to the data base, does its job and then closes the connection. The first session creates the features and the training set in the data base. The second session creates the classifiers and stores them there. And the third session verifies the classifiers built.

File example4.adb:

`with Ada.Characters.Handling; use Ada.Characters.Handling; with Ada.Exceptions; use Ada.Exceptions; with Ada.Text_IO; use Ada.Text_IO; with Confidence_Factors.Edit; use Confidence_Factors.Edit; with Fuzzy.Classifier.Handle; use Fuzzy.Classifier.Handle; with Fuzzy.Feature.Handle; use Fuzzy.Feature.Handle; with Fuzzy.Feature.Handle.Edit; use Fuzzy.Feature.Handle.Edit; with Fuzzy.Feature.Handle.Factory; use Fuzzy.Feature.Handle.Factory; with Fuzzy.Intuitionistic; use Fuzzy.Intuitionistic; with Fuzzy.Lecture.Handle; use Fuzzy.Lecture.Handle; with Fuzzy.Lecture.Handle.Bulk; use Fuzzy.Lecture.Handle.Bulk; with Fuzzy.Lecture.Handle.Text_IO; use Fuzzy.Lecture.Handle.Text_IO; with Fuzzy.Persistence; use Fuzzy.Persistence; with Indicator.Text_IO; use Indicator.Text_IO; with Integer_Intervals; use Integer_Intervals; with Persistent.Handle; use Persistent.Handle; with Persistent.Native_ODBC.Lectures; use Persistent.Native_ODBC.Lectures; with Strings_Edit.UTF8.Maps; use Strings_Edit.UTF8.Maps; with Test_ODBC_Session; use Test_ODBC_Session; with Name_Tables; with Fuzzy.Classifier.Handle.Factory; use Fuzzy.Classifier.Handle.Factory; with Fuzzy.Feature.Handle.Bounded_Arrays; use Fuzzy.Feature.Handle.Bounded_Arrays; procedure Example4 is begin -- -- First we should make minus ('-') legal for names of discrete -- feature values, because the teaching set contains values -- containing minus (like in 'mod-stable'). -- Name_Tables.Name_Body := Name_Tables.Name_Body or To_Set ("-");`

By default '-' is not a valid character in a value. So the character '-' is added to the set of valid characters for the names of feature domain points, because the training set contains values like mod-stable.

File example4.adb (continued, the first session):

`--------------------------------------------------------------------- -- The first session with the data base. Here we create the training -- set, classes and the features we will use. -- declare Data_Base : Storage_Handle; Training_Set : Lecture_Handle; -- -- Features is the list of all features the teaching set defines. -- The last feature is the classes (the class-feature). -- Features : Feature_Array := ( Create_Discrete ("L-CORE", "high, mid, low"), Create_Discrete ("L-SURF", "high, mid, low"), Create_Discrete ("L-O2", "excellent, good, fair, poor"), Create_Discrete ("L-BP", "high, mid, low"), Create_Discrete ("SURF-STBL", "stable, mod-stable, unstable"), Create_Discrete ("CORE-STBL", "stable, mod-stable, unstable"), Create_Discrete ("BP-STBL", "stable, mod-stable, unstable"), Create_Float ("COMFORT", 5, 0.0, 20.0), Create_Discrete ("ADM-DECS", "I, S, A") ); begin`

In the first session we create the features we are using. Most of them are discrete features. A discrete feature is created by calling Fuzzy.Feature.Handle.Factory.Create_Discrete. Only the feature COMFORT is a floating-point one. It is created by Fuzzy.Feature.Handle.Factory.Create_Float. Handles to the created features are placed into the array Features.

File example4.adb (continued, the first session):

`Put_Line ("Opening a connection to data base (via ODBC driver)"); Put_Line ("Ensure that you have configured the server and"); Put_Line ("have created a data base to access, before"); Put_Line ("you enter the following data:"); Data_Base := Open; Put_Line ("Session one. Creating the training set");`

Here the procedure Open, defined in Test_ODBC_Session, is used to connect to the data base. When called for the first time it prompts for the data base server, user name and password. Once successfully connected it will use them for all further connections. Open will return a handle to the persistent storage object. It also will erase the data base contents when connected first time.

File example4.adb (continued, the first session):

`-- -- Storing all features into the data base. The name of a feature -- in the data base will be identical to the feature name. -- for Index in Features'Range loop Put ( Data_Base, Features (Index), Get_Name (Features (Index)) ); end loop;`

The loop above stores all features into the data base by calling Fuzzy.Persistence.Put. The external name of a feature will be one of the feature. For this Fuzzy.Feature.Handle.Get_Name is called.

File example4.adb (continued, the first session):

`-- -- Creating a training set in the data base -- Training_Set := Create (Data_Base, "Training set");`

Next to the loop, the training set is created by a call to Persistent.Native_ODBC.Lectures.Create. We could do it also by Fuzzy.Lecture.Handle.Factory.Create_Persistent which supports persistent training sets for different types of storage. Or we could as well create a memory-mapped training set and then store it into the data base, but Persistent.Native_ODBC.Lectures.Create (and Create_Persistent) provides "native" data-base-resident training set. They do not require to be completely loaded into the memory.

File example4.adb (continued, the first session):

`-- -- Reading training examples from a file into the set -- declare Suffix : aliased String := " examples read"; Progress : aliased Counter (Suffix'Access); Transaction : Lecture_Update (Ptr (Training_Set)); begin Read ( File_Name => "example4.txt", Lesson => Training_Set, Features => Features, Viewer => Progress'Access ); New_Line; end; end;`

Finally, Fuzzy.Lecture.Handle.Text_IO.Read is called to get the training set from the file example4.txt. The features array determines the order of feature columns in the file. Immediately after that we close the session, by just leaving the scope of the variable Data_Base, which is a handle to the persistent storage. This causes closes the connection to the data base, and so the features and the training set remain only in the data base. Note the declaration of the variable Transaction of the type Lecture_Update. For some storage types backing training sets this could sufficiently improve performance. The variable Progress is the progress indicator that prints the example number with the value of Suffix added.

File example4.adb (continued, the second session):

`--------------------------------------------------------------------- -- The second session. Here we use the training set for creating a -- graph-scheme. Then the graph-scheme is also stored in the data -- base. -- declare Data_Base : Storage_Handle; Training_Set : Lecture_Handle; Classifier : Classifier_Handle; Features : Feature_Array (1..8); Classes : Feature_Handle; begin Data_Base := Open; Put_Line ("Session two. Learning"); -- -- Getting a handle to the training set in the data base -- Training_Set := Get (Data_Base, "Training set"); -- -- Getting the features we want to use for learning -- Features (1) := Get (Data_Base, "L-CORE"); Features (2) := Get (Data_Base, "L-SURF"); Features (3) := Get (Data_Base, "L-O2"); Features (4) := Get (Data_Base, "L-BP"); Features (5) := Get (Data_Base, "SURF-STBL"); Features (6) := Get (Data_Base, "CORE-STBL"); Features (7) := Get (Data_Base, "BP-STBL"); Features (8) := Get (Data_Base, "COMFORT"); -- -- Get the class-feature -- Classes := Get (Data_Base, "ADM-DECS");`

The second session with the data base starts with re-opening it by Open and restoring the training set and the features array. Note that when the training set is restored using Fuzzy.Persistence.Get, all the features it uses are restored as well. So the array of features could be queried from the training set as well. Though in this example we rather use an explicit call to Fuzzy.Persistence.Get for each feature with the same effect.

File example4.adb (continued, the second session):

`-- -- Learn from the first 3/4 of the reaching set. The result of -- training, a classifier, is stored into the data base. -- declare Progress : aliased Timed_Bar (20); begin Classifier := Learn ( Lesson => Training_Set, Features => Features, Classes => Classes, To => (Get_Examples_Number (Training_Set) * 3) / 4, Viewer => Progress'Access ); New_Line; end; Put (Data_Base, Classifier, "Classifier1");`

After features and the training set are ready, Learn from Fuzzy.Classifier.Handle is used to learn from the first 3/4 of the training set. The variable Progress is used to indicate training progress. The a handle to obtained classifier is then stored into the data base under the name Classifier1.

File example4.adb (continued, the end of the second session):

`-- -- Here we create another classifier by splitting the feature -- COMFORT into several binary features and distributing them in -- the feature list. The obtained classifier is stored under -- another name. -- declare Binary : Bounded_Array := Create_Binary (Features (8)); Progress : aliased Timed_Bar (20); begin Put ("Learning on binary features "); Classifier := Learn ( Lesson => Training_Set, Features => ( Ref (Binary, 1), -- The MSB of comfort Ref (Binary, 2), -- The second bit of comfort Ref (Binary, 3), -- The last bit of comfort Features (1), -- Internal temperature Features (2), -- Surface temperature Features (3), -- Oxygen saturation Features (4), -- Last blood pressure Features (5), -- Stability of surface temperature Features (6), -- Stability of core temperature Features (7) -- Stability of blood pressure ), Classes => Classes, To => (Get_Examples_Number (Training_Set) * 3) / 4, Viewer => Progress'Access ); New_Line; Classifier := Separator (Classifier); Put (Data_Base, Classifier, "Classifier2"); end; end;`

In this fragment the feature COMFORT is replaced by a set of binary features. To produce binary features Fuzzy.Feature.Handle.Factory.Create_Binary is called. It returns an array of the binary features named Binary. This classifier is saved as Classifier2. Note that the binary features used in the classifier need not to be explicitly stored into the data base. It is made automatically when the classifier is stored. This ends the second session.

File example4.adb (continued, the third session):

`--------------------------------------------------------------------- -- The third session. Here we use the classifier and the rest of the -- training set to verify the quality of learning. -- declare Data_Base : Storage_Handle; Training_Set : Lecture_Handle; Classifier : Classifier_Handle; Result : Fuzzy.Intuitionistic.Set (3); begin Data_Base := Open; Put_Line ("Session three. Testing the classifier"); -- -- Getting a handle to the training set and the classifier stored -- in the data base -- Training_Set := Get (Data_Base, "Training set"); Classifier := Get (Data_Base, "Classifier1"); -- -- Classify the rest 1/4 of the training set -- Result := Verify ( Classifier, Training_Set, From => (Get_Examples_Number (Training_Set) * 3) / 4 + 1 ); Put_Line ("The classification error means:"); for Index in 1..Result.Cardinality loop Put_Line ( Image (Get_Classes (Classifier), Interval'(Index, Index)) & ": [" & Image (Result.Possibility (Index)) & ".." & Image (Result.Necessity (Index)) & "]" ); end loop;`

In the last session we restore the training set and the classifier and classify the rest 1/4 of the training set to verify the classifiers. First it does this for the Classifier1.

File example4.adb (continued, the third session, the second classifier test):

`-- -- Here we repeat that for the second classifier -- Classifier := Get (Data_Base, "Classifier2"); Result := Verify ( Classifier, Training_Set, From => (Get_Examples_Number (Training_Set) * 3) / 4 + 1 ); Put_Line ("The error means with binary features:"); Put_Line ("The classification error means:"); for Index in 1..Result.Cardinality loop Put_Line ( Image (Get_Classes (Classifier), Interval'(Index, Index)) & ": [" & Image (Result.Possibility (Index)) & ".." & Image (Result.Necessity (Index)) & "]" ); end loop; end; exception when Error : others => Put_Line (Exception_Information (Error)); end Example4;`

Then the Classifier2 is tested. The classifier using binary features reaches slightly better accuracy (about 70%). The difference can be explained by a better balance between tested features, as the low significant bits of the feature COMFORT are tested at later stages than in the first classifier. Note though that binary features have to be used with care. Especially when the training sets are short, as in this example, because of possible overtraining.

## 5. Packages

There are two separate sets of packages public interface package and implementation packages.

### 5.1. Public interface packages

Package | Provides
Fuzzy | See general fuzzy sets handling
| Classifier |
| Handle | Handles to classifiers and the operations on them, such as classification and learning
| Factory | Functions to create new classifiers by training
HTML | HTML output of classifiers
Feature |
| Domain_Float_Handle | Operations common to all floating-point features based on the type Domain_Float
Domain_Integer_Handle | Operations common to all integer features based on the type Domain_Integer
Float_Handle | Operations specific to the floating-point interval features based on the type Domain_Float
Handle | Handles to fuzzy features
| Bounded_Arrays | Bounded arrays of handles to fuzzy features
Container | Sets of handles to fuzzy features
Edit | String I/O for values, intervals, images, classifications and estimations of fuzzy features
Factory | Functions to create new fuzzy features
HTML | HTML output of images, classifications and estimations of features
Tables | String to fuzzy feature handle mapping
Unbounded_Arrays | Unbounded arrays of handles to fuzzy features
Integer_Handle | Operations specific to the integer features based on the type Domain_Integer
Isosceles Trapezoids_Handle | Operations specific to the floating-point isosceles trapezoid features based on the type Domain_Float
Linguistic_Handle | Operations specific to the floating-point linguistic features based on the type Domain_Float
Output_Handle | Operations specific to the floating-point output features based on the type Domain_Float
| Center_Of_Area | Factory of center of area defuzzifiers
Center_Of_Gravity | Factory of center of gravity defuzzifiers
Discrete_Center_Of_Gravity | Factory of discrete center of gravity defuzzifiers
Leftmost_Max | Factory of leftmost maximum defuzzifiers
Rightmost_Max | Factory of rightmost maximum defuzzifiers
Graph |
| Handle | Handles to fuzzy graph nodes
| Bounded_Arrays | Bounded array of fuzzy graph nodes
Container | Sets of fuzzy graph nodes
Edit | String I/O of fuzzy graphs
HTML | HTML output of fuzzy graphs
Layer | Advanced operations of fuzzy graphs and their nodes
Learning | Training on individual graph nodes (it is recommended to use Fuzzy.Classifier.Handle instead.)
Manual | Manual creation of graph nodes
Transformations | Higher-level operations on graph nodes
Lecture |
| Handle | Handles to training sets
| Factory | Functions to create new training sets of different kinds
HTML | HTML output of training sets
Tables | String to training set handle mapping
Text_IO | Input of training examples from text files
Persistence | Operations for dealing with persistent features, classifiers, training sets, graphs
HTML | Things common for HTML output
Indicator |
| Handle | Handles to progress indication objects

The packages described in separated documents:

- General fuzzy sets handling;
- Component library;
- General strings edit;
- Tables management.

### 5.2. Private (implementation) packages

Package | Provides
APQ |
| Lectures | APQ-specific routines for dealing with training sets
Fuzzy | See general fuzzy sets handling
| Classifier | The interface of abstract fuzzy classifier objects
| HTML | HTML output of fuzzy classifiers
Identity | Implementation of identity classifiers
Separator | Implementation of fuzzy classifiers for separated, complete sets of classes
Feature | The interface of abstract fuzzy feature objects
| Binary | Implementation of binary feature objects
Comparisons | Feature comparisons defined on pointers
| Mutually_Independent | Implementation of mutually independent binary feature objects
Classificatory | Implementation of classificatory feature objects
Context | Contexts based on training sets, Lecture_Context
Data | Implementation of context-cached feature data
Discrete | Implementation of discrete feature objects (dynamic)
Edit | String editing of fuzzy feature values, intervals, sets, classifications, estimations
Floats | The type Domain_Float and other dependent types used for pre-defined floating-point features (an instance of Fuzzy.Feature.Generic_Domain_Float)
| Center_Of_Area | Center of area defuzzification function for the type Domain_Float
Center_Of_Gravity | Center of gravity defuzzification function for the type Domain_Float
Discrete_Center_Of_Gravity | Discrete center of gravity defuzzification function for the type Domain_Float
Leftmost_Max | Leftmost maximum defuzzification function for the type Domain_Float
Rightmost_Max | Rightmost maximum defuzzification function for the type Domain_Float
Generic_Discrete | Implementation of discrete feature objects (generic)
Generic_Domain_Float | Interface and implementation of abstract floating-point feature objects (generic). The following packages are instantiated in the specification of the package:
Package | Instance of | Provides
Derived_Measures | Measures_Derived | Derived units
Float_Edit | Strings_Edit.Float_Edit | String I/O for floating-point numbers
Float_Intervals | Intervals.Floats | Intervals with floating-point bounds. The type Interval.
Float_Measures | Measures | Dimensioned floating-point numbers. The type Measure
Fuzzy_Floats | Fuzzy.Floats | Floating-point fuzzy numbers. The type Fuzzy_Float
Fuzzy_Measures | Fuzzy.Measures | Dimensioned fuzzy numbers. The type Fuzzy_Measure
Interval_Measures | Intervals.Measures | Dimensioned intervals. The type Interval_Measure
Irregular_Measures | Measures_Irregular | Irregular units
Measure_Edit | Measures_Universal_Edit | String I/O of dimensioned values
Variables | Fuzzy.Linguistics | Linguistic variables. The type Variable
Variable_Edit | Fuzzy.Linguistics.Edit | String I/O of linguistic variables
Variable_Measures | Fuzzy.Measures.Linguistics | Dimensioned linguistic variables. The type Variable_Measure
Variable_Measure_Sets | Fuzzy.Measures.Linguistics.Sets | Dimensioned sets of linguistic variables. The type Set_Measure
Variable_Sets | Fuzzy.Linguistics.Sets | Sets of linguistic variables. The type Linguistic_Set
Variable_Set_Edit | Fuzzy.Linguistics.Sets.Edit | String I/O of sets of linguistic variables
Generic_Defuzzifier | Interface of abstract defuzzifier objects (generic)
| Generic_Handle | Handles to defuzzifier objects (generic)
| Generic_Method | Factory of defuzzifier objects (generic)
Generic_Output | Floating-point output features (generic)
Generic_Float | Floating-point interval features (generic)
Generic_Handle | Operations common to all floating-point features (generic)
Generic_Linguistic | Floating-point linguistic features (generic)
| Generic_Isosceles_Trapezoids | Floating-point isosceles trapezoid features (generic)
Generic_Domain_Integer | Interface and implementation of abstract integer feature objects (generic). The following packages are instantiated in the specification of the package:
Package | Instance of | Provides
Fuzzy_Integers | Fuzzy.Integers | Integer fuzzy numbers. The type Fuzzy_Integer
Integer_Edit | Strings_Edit.Integer_Edit | String I/O for integer numbers
Integer_Intervals | Intervals.Integers | Integer intervals. The type Interval.
Generic_Handle | Operations common to all integer features (generic)
Generic_Integer | Integer features based on singletons
Generic_Independent | Implementation of abstract independent feature objects (generic)
HTML | HTML output of fuzzy sets, classifications, estimations
Independent | Common base for objects of independent fuzzy features (an instance of Generic_Independent)
Integers | The type Domain_Integer and other dependent types used for in pre-defined integer features (an instance of Generic_Domain_Integer)
Sets | Sets of features (known to exist longer than the set)
Graph | The interface of abstract fuzzy graph node objects
| Comparisons | Node comparisons defined on pointers
Edit | String editing for graph nodes
HTML | HTML output of graph nodes
Learning | The common base for learning of fuzzy graphs
| Implementation | Generic implementation of learning with graphs. It is instantiated for each feature image separately
| Necessity | A generic part of implementation used for learning from the images related to necessities
Memory_Resident | An implementation of fuzzy graph nodes
| Clustering_Branch | Clustering branch nodes
Branch | Branch nodes
Leaf | Leaf nodes
Node_Class_Sets | Sets of node equivalence classes. Each class of equivalence consists of nodes delivering equivalent classifications. It is used for factoring out the nodes suitable for re-use
Node_Sets | Sets of nodes
Scheme | Implementation of graph-schemes
Lecture | The interface of abstract fuzzy training set objects
| Block | Abstract interface of a training set block
| Dotted | Implementation of a block of singletons in a memory-resident training set
General | Implementation of a block of general case images in a memory-resident training set
Composite | Derived training sets, composed of examples of the reference sets
Connotated | Abstract fuzzy training sets supporting lists of features used. It is reused in concrete implementations of the sets
Container | Sets of handles to training sets
General | Memory-resident fuzzy training sets
| Text_Dialogue | Memory-resident fuzzy training sets with querying missing data using console I/O
HTML | HTML output of fuzzy training sets
Subrange | Derived training sets, containing a range of examples of the reference set
Text_IO | Text input of fuzzy training sets
GNU |
| DB |
| SQLCLI |
| Lectures | ODBC-specific routines for dealing with training sets
Indicator | Progress indicators abstract interface
| Text_IO | Indicators used for console output through standard text I/O
Persistent | See component library
| APQ | See component library
| Lectures | Implementation of training sets resident in a data base interfaced through APQ
Native_ODBC | See component library
| Lectures | Implementation of training sets resident in a data base interfaced through ODBC
ODBC | See component library
| Lectures | Implementation of training sets resident in a data base interfaced through GNADE ODBC

### 5.3. Changes log

The following versions were tested with the compilers:

- GNAT Studio Community 2020 (20200427)
- GNAT Community 2019 (20190517-83)
- GNAT Community 2018 (20180523-73)
- GNAT 8-12

and the GtkAda versions:

- GtkAda 3.14.15
- GtkAda April 5, 2022 (GTK 3.24.33)

Changes (22 May 2022) to the version 1.11:

- Adapted to GNAT 12.1 and Fedora 36.

Changes (16 April 2022) to the version 1.10:

- GNAT Studio Community 2021 bugs worked around;
- GTK 3.24.x support.

Changes (31 May 2020) to the version 1.9:

- Code cleanup;
- Adapted to GNAT Studio Community 2020.

The following versions were tested with the compilers:

- GNAT Community 2018 (20180523-73)
- GNAT 8

and the GtkAda versions:

- GtkAda 3.14.15

Changes (5 Aug 2018) to the version 1.8:

- This version supports both 32-bit and natively 64-bit Windows.

Changes (25 July 2016) to the version 1.7:

- Compatibility with GtkAda 3.14

The following versions were tested with the compilers:

- GNAT GPL 2015 (20150428-49)
- GNAT 4.9.2

and the GtkAda versions:

- GtkAda 3.8.3

Changes (29 June 2015) to the version 1.6:

- Adapted to GNAT GPL 2015.

The following versions were tested with the compilers:

- GNAT GPL 2014 (20140331)
- GNAT 4.8.2 (20131212)
- GNAT 4.9.0

and the GtkAda versions:

- GtkAda 3.8.2

Changes (2 April 2015) to the version 1.5:

- ARMv7 (AKA armhf) support.

Changes (25 November 2014) to the version 1.4:

- Native Ada persistence layer support added;
- Minor bug fixes.

Changes (1 June 2014) to the version 1.3:

- The GUI is adapted for the GTK 3.x. GTK 2.x is no more supported;
- Null exclusion is consistently added to the interfaces;
- Handle types made publicly tagged;
- Compiled with GNAT 4.9.

Changes (14 October 2012) to the version 1.2:

- The persistence layer is now based on native ODBC bindings. GNADE ODBC and APQ bindings are depreciated and no longer supported.

Changes to the version 1.1:

- Minor bug fixes in importing training sets;
- Windows distribution has hicolor icon themes included.

Changes to the version 0.1:

- Packaged for Debian and Fedora;
- Minor bug fixes.

The first version 0.1.

## 6. Table of Contents

1 A necessary introduction 1.1. Fuzzy graph-schemes 2 Public interfaces 2.1. Objects and handles 2.2. Containers 2.3. Fuzzy features 2.3.1. Handles to features 2.3.2. Feature containers 2.3.3. Feature factory 2.3.4. String edit 2.3.5. Output in HTML format 2.3.6. Handles to integer features 2.3.7. Handles to floating-point features 2.4. Training sets 2.4.1. Handles to training sets 2.4.2. Creating training sets 2.4.3. Output in HTML format 2.4.4. Text file IO 2.4.5. Training sets containers 2.4.6. Bulk training set operations 2.5. Classifiers 2.5.1. Handles to classifiers 2.5.2. Creating classifiers 2.5.3. Output in HTML format 2.6. Graphs 2.6.1. Handles to nodes 2.6.2. Node containers 2.6.3. Operations on graphs 2.6.4. Manual creation of graphs 2.6.5. Learning 2.6.6. String edit 2.6.7. Output in HTML format 2.6.8. Graph transformations 2.7. Persistence 2.8. Progress indicators 2.9. Defuzzifiers 2.9.1. Defuzzifier factories 3 Private interfaces 3.1. Feature objects 3.1.1. Types 3.1.2. Operations 3.1.3. Independent features 3.1.4. Generic discrete features | 3.1.5. Dynamic discrete features 3.1.6. Generic integer features 3.1.7. Generic floating-point features 3.1.8. Binary features 3.1.9. Classificatory features 3.1.10. Feature data 3.1.11. Feature contexts 3.2. Training set objects 3.2.1. Primitive operations 3.2.2. Class-wide operations 3.2.3. Other operations and types 3.2.4. Subrange training set 3.2.5. Composite training set 3.3. Classifiers 3.3.1. Types 3.3.2. Primitive operations on classifiers 3.3.3. Class-wide operations and data 3.3.4. Graph-schemes 3.3.5. Separating classifiers 3.3.6. Identity classifiers 3.4. Node objects 3.4.1. Types 3.4.2. Primitive operations on nodes 3.4.3. Primitive operations on factories 3.4.4. Other operations on nodes 3.4.5. Training nodes 3.5. Indicator objects 3.5.1. Indicators based on text I/O 3.6. Defuzzifier objects 3.6.1. Generic defuzzifiers 3.6.2. Generic handles to defuzzifiers 3.6.3. Generic factory of defuzzifiers 4 Examples 4.1. Example 1. Creation of a training set 4.2. Example 2. Manual creation of a graph 4.3. Example 3. Learning from a training set 4.4. Example 4. Working with a data base 5 Packages 5.1. Public interface packages 5.2. Private (implementation) packages 5.3. Changes log 6 Table of contents