Skip to content

Fuzzy Logic Fundamentals

Fuzzy logic extends classical (boolean) logic to handle degrees of truth. Instead of “true or false,” fuzzy logic allows “partly true” — a value between 0.0 and 1.0. This is essential for reasoning about real-world data that is inherently imprecise, vague, or uncertain.

Consider the question: “Is 36.8°C a fever?”

In classical logic, you need a hard cutoff: fever ≥ 37.5°C. So 37.4°C is “not a fever” and 37.5°C is “a fever.” This doesn’t match how doctors actually think — 37.4°C is concerning, just less so than 39°C.

Fuzzy logic lets you express this naturally:

Temperature Classical (true/false) Fuzzy (degree)
36.0°C Not a fever 0.0
37.0°C Not a fever 0.2
37.5°C Fever 0.5
38.0°C Fever 0.8
39.0°C Fever 1.0

The fuzzy approach captures the gradual transition from “definitely not a fever” to “definitely a fever.”

A membership function defines how strongly a value belongs to a fuzzy set. It maps a crisp input (like 37.5°C) to a degree of membership (like 0.5).

The Reasoning Layer supports four shapes:

Triangular — simple peak with linear ramps:

1.0 │ /\
│ / \
0.5 │ / \
│ / \
0.0 │───/────────\───
│ a b c
  • a: left foot (membership = 0)
  • b: peak (membership = 1)
  • c: right foot (membership = 0)
FuzzyShape.triangular(36, 37.5, 39);
// "fever" peaks at 37.5, zero below 36 and above 39

Trapezoidal — flat top with linear ramps:

1.0 │ ┌────┐
│ / \
0.5 │ / \
│ / \
0.0 │──/────────────\──
│ a b c d
  • Flat top between b and c (membership = 1)
  • Linear ramps from a to b and from c to d
FuzzyShape.trapezoidal(20, 22, 26, 28);
// "comfortable temperature" is fully 1.0 between 22-26°C

Gaussian — smooth bell curve:

1.0 │ ╭─╮
│ ╱ ╲
0.5 │ ╱ ╲
│ ╱ ╲
0.0 │╱───────────────╲
│ mean
FuzzyShape.gaussian(100, 15);
// centered at 100, spreading with std_dev 15

Cyclic Gaussian — wraps around a period (for angles, time-of-day, etc.):

FuzzyShape.cyclicGaussian(180, 30, 360);
// centered at 180°, wraps around the 360° period

A truth degree is a number between 0.0 and 1.0 that represents how true a statement is:

Degree Interpretation
0.0 Definitely false
0.25 Mostly false
0.5 Neither true nor false
0.75 Mostly true
1.0 Definitely true

In the Reasoning Layer, every inference solution has a certainty score (a truth degree). When fuzzy rules chain together, truth degrees propagate through the chain.

When a rule has multiple antecedents, how do you combine their truth degrees? T-norms define different strategies:

Rule: comfortable(room) :- good_temp(room) AND good_humidity(room)

If good_temp has degree 0.8 and good_humidity has degree 0.6:

T-norm Formula Result Behavior
min min(0.8, 0.6) 0.6 Conservative — the weakest link determines the result
product 0.8 × 0.6 0.48 Probabilistic — combined confidence drops
lukasiewicz max(0, 0.8 + 0.6 - 1) 0.4 Strict — strongly penalizes low degrees

Choose based on your domain:

  • min for safety-critical applications (pessimistic)
  • product for probabilistic reasoning (balanced)
  • lukasiewicz for strict requirements (punishes uncertainty)
const result = await client.inference.fuzzyProve({
goal: psi('comfortable', {
room: '?Room',
}),
tnorm: 'product', // how to combine truth degrees
minDegree: 0.3, // filter out solutions below this threshold
});

Attach fuzzy values to term features to represent imprecise measurements:

import { Value, FuzzyShape, constrained, guard, psi } from '@kortexya/reasoninglayer';
const reading = await client.terms.createTerm({
sortId: sensorSortId,
ownerId: userId,
features: {
location: 'lab-1',
// "Temperature is approximately 22°C (±2°C)"
temperature: Value.fuzzyNumber(FuzzyShape.triangular(20, 22, 24)),
// "Humidity reading of 65% with 90% confidence"
humidity: Value.fuzzyScalar(65, 0.9),
},
});

Fuzzy inference propagates truth degrees through rule chains:

// Fact with certainty 0.9
await client.inference.addFact({
term: psi('sensor_reading', {
location: 'lab-1',
temperature: 38,
}),
});
// Rule with certainty 0.85
await client.inference.addRule({
term: psi('overheating', {
location: '?Location',
}),
antecedents: [
psi('sensor_reading', {
location: '?Location',
temperature: constrained('?Temp', guard('gt', 35)),
}),
],
certainty: 0.85,
});
// Fuzzy proof: combined certainty = 0.9 × 0.85 = 0.765 (with product t-norm)
const result = await client.inference.fuzzyProve({
goal: psi('overheating', {
location: '?Location',
}),
tnorm: 'product',
});

The Reasoning Layer provides several fuzzy operations beyond basic inference:

Operation What it does Use case
Fuzzy unification Computes similarity degree between two terms “How similar are these two sensor readings?”
Fuzzy merge Combines features from two terms “Merge these two partial observations”
Fuzzy subsumption Checks if one term is more specific than another “Is this reading consistent with the expected range?”
Top-K search Finds the K most similar terms “Find the 10 closest matches to this pattern”
Effect prediction Predicts an outcome by aggregating similar past cases “Based on similar past cases, what’s the likely effect?”

For detailed usage of each operation, see the Fuzzy Logic guide.

Fuzzy logic and probability theory are often confused, but they answer different questions:

Fuzzy logic Probability
Question “To what degree is this true?” “What’s the chance this is true?”
Example “This 37.2°C reading is a fever to degree 0.3” “There’s a 30% chance this person has a fever”
Values Degrees of membership (vagueness) Likelihoods of events (randomness)
Complement Not necessarily: fuzzy(“tall”) + fuzzy(“short”) can exceed 1.0 P(A) + P(not A) = 1.0 always

The Reasoning Layer supports both: fuzzy logic for vagueness/imprecision, and Bayesian prediction for probabilistic reasoning. You can even combine them.

  1. Fuzzy logic handles “how much” rather than “yes or no” — real-world data is rarely boolean
  2. Membership functions define the shape of fuzzy concepts (triangular, trapezoidal, Gaussian)
  3. Truth degrees propagate through inference rules, giving every conclusion a confidence level
  4. T-norms control how truth degrees combine — choose based on how conservative you need to be
  5. Fuzzy operations (unification, merge, subsumption, search) work on entire terms, not just individual values