After several weeks away from this blog, I would like to start up again with the exciting field of fuzzy logic. Most introductions to fuzzy logic talk about how everything is different, and overview the three major types: Gödel, product, and Lukasiewicz, but I'm going to take a different approach. I'm going to stick with product fuzzy logic for the remainder of this post.
Product Fuzzy Logic
It is important to discuss domains when regarding operations, and fuzzy logic is somewhat consistent in its use of the domain [0, 1], which includes 0, 1 and all the real numbers in between. Let's call this the
Clamp datatype. There are obvious mappings to and from
Bool: 0 maps to
False, 1 maps to
True, and the in betweens can be handled on a case-by-case basis (possibly to throw and error or something).
The operations on the
Clamp datatype would be both arithmetic and logic operations, which would include addition, subtraction, multiplication, division, conjunction (and), and disjuction (or). How would these be defined in product fuzzy logic? According to the product T-norm (the fancy name for how "and" is defined), the logic operations would be defined as
- not(x) = 1 - x
- and(x, y) = xy
- or(x, y) = x + y - xy
- implies(x, y) = 1 - x(1 - y)
One interesting thing about product fuzzy logic is that there are multiple ways of defining equiv, depending on what properties you are looking for. One possibility is that equiv(x, y) = and(implies(x, y), implies(y, x)), which would mean that it would have to be defined as equiv(x, y) = (1 - x - y + 3xy - yx2 - xy2 + x2y2). This is quite a mess, and the same effect (in terms of mapping to
Bool) can be accomplished by the definition equiv(x, y) = (1 - x - y + 2xy).
Other considerations for operations on the
Clamp datatype are that when performing arithmetic operations, the output of the normal operation must be minimized or maximized to fall within the range [0, 1]. This may have the unfortunate side effect of many run-time errors, or unexpected mathematical outputs. If all conversions to and from the
Clamp datatype are excplicit, then this is not a problem.
Just as the
String is the basis for the text field widget, the
Clamp datatype can be thought of as the basis for the scrollbar widget. Scrollbars are usually tied to a viewport, which can contain an image, a document, or a webpage. Usually the viewport has all the information that the scrollbar needs to do its job. It has height and width information of the entire image, and the height and width information of the part that is showing. Using this information, the only additional information that needs to be stored in the scrollbar is the percentage of how far down on the scrollbar you are, which is equivalent to what the
Clamp datatype provides.
Why is it that such a fundamental datatype like
Clamp is not found in more programming languages? Usually it is defined as equivalent to
Double, and intended to be used with values between 0.0 and 1.0, but no strict validation or bounds checking are done to ensure that this is so. One example where this kind of usage is found is in OpenGL, which we will talk about next.In OpenGL, one of the datatypes that is pervasive throughout the API is the
GLclamp datatype. This is also a value between 0 and 1, and also where I got the name from. With this datatype, OpenGL defines some texture and image datatypes as structure with members of this type, for example a color in OpenGL is a structure with 3
With so many applications, the
Clamp datatype is a prime example of a design goal that I've been trying to find a name for. When abstractions are too low-level, then you may have few abstractions (like bit and byte), but using these abstractions is a nightmare (just look at assembly code). When abstractions are too high-level, then you may be able to use them easily (like drag-and-drop database form designers), but the number of abstractions makes a steep learning curve, and a high pressure on the discovery of abstractions other people have made (for example: some game libraries have 3 types of fog, and dozens of types of meshes, depending on whether you want to add skeletons or water ripples, etc.). The design goal I'm trying to acheive is a balance of these two extremes that balances low-level abstraction and high-level abstraction in such a way that there are few abstractions, and using them is easy. I think
Clamp datatype meets both of these requirements.
From fuzzy logic to colors to scollbars,
Clamp seems to form the basis of an unrecognized basis for computation that may be useful in the future.