Skip to content

Historical-to-Modern API Migration Examples

Migration rule

Historical names remain supported. Existing users do not need to rename MFunction, FuzzySet, FuzzyScale, UniversalFuzzyScale, Defuz, or the scalar operator functions merely to adopt version 2. Migrate one area at a time when the focused API already provides the behavior the application needs.

The current modern API covers explicit domains, immutable scalar fuzzy sets, set algebra, relations, derived properties, alpha-cuts, exact height-aware normalization, and typed linguistic-term and ordered-scale representations. A focused immutable membership-function factory is also available through fuzzyroutines.membership. Exact and Unicode case-insensitive typed scale lookup plus explicit fuzzification policies are available. Explicit-grid coverage, overlap, gap, and partition diagnostics are also available without changing membership coefficients. Modern centroid defuzzification is available through an explicit integration domain and numerical policy. The examples below keep remaining gaps visible instead of inventing future call shapes.

Area Historical API remains supported Preferred path available today
Operators FuzzyNOT, TNorm, SCoNorm, and compose functions NegationPolicy, TNormPolicy, and SNormPolicy; set operations require policies explicitly
Membership functions MFunction and every protected historical identifier Immutable callable factories in fuzzyroutines.membership, including conventional Triangle and Trapezoid
Fuzzy sets Mutable FuzzySet with a legacy supportSet integration interval Immutable ScalarFuzzySet with an explicit ContinuousUniverse or DiscreteUniverse
Scales FuzzyScale and UniversalFuzzyScale Typed representation, lookup, fuzzification, and sampled diagnostics through LinguisticScale
Derived operations No equivalent unified modern surface DeriveProperties, AlphaCut, SampleAlphaCut, Height, and Normalize preserve explicit exactness boundaries
Defuzzification FuzzySet.Defuz() and defuzValue Centroid() with explicit ScalarFuzzySet, IntegrationDomain, and optional CentroidPolicy

Operators

Historical scalar calls select a family with a string:

from fuzzyroutines.FuzzyRoutines import FuzzyNOT, SCoNorm, TNorm

conjunction = TNorm(0.4, 0.7, normType="algebraic")
disjunction = SCoNorm(0.4, 0.7, normType="logic")
negated = FuzzyNOT(0.4)

The modern scalar and fuzzy-set paths make the selected policy an immutable value:

from fuzzyroutines import NegationPolicy, SNormPolicy, TNormPolicy

conjunction = TNormPolicy("algebraic").Evaluate(0.4, 0.7)
disjunction = SNormPolicy("logic").Evaluate(0.4, 0.7)
negated = NegationPolicy("standard").Evaluate(0.4)

TNormCompose and SCoNormCompose do not yet have focused modern counterparts. Keep those historical names when n-ary composition is required; do not replace them with an undocumented API.

Membership functions

The historical factory and parameter conventions remain the executable API:

from fuzzyroutines.FuzzyRoutines import MFunction

# Historical order is preserved: a = left foot, c = apex, b = right foot.
membershipFunction = MFunction("triangle", a=0.0, b=1.0, c=0.5)
grade = membershipFunction.mju(0.25)

For new code, use the immutable modern callable directly:

from fuzzyroutines import ContinuousUniverse, ScalarFuzzySet
from fuzzyroutines.membership import Triangle

membershipFunction = Triangle(left=0.0, peak=0.5, right=1.0)
universe = ContinuousUniverse(0.0, 1.0, leftClosed=True, rightClosed=True)
fuzzySet = ScalarFuzzySet(universe, membershipFunction)

Additive registry names such as gaussian, logistic, sShoulder, and harringtonDesirability are available, but migration does not require renaming exponential, sigmoidal, parabolic, or desirability. See the membership-function contract before changing any identifier because some historical parameter orders are deliberately preserved.

The modern Triangle(left, peak, right) contract deliberately differs from historical MFunction("triangle", a=left, b=right, c=peak). Modern Trapezoid(left, plateauStart, plateauEnd, right) similarly differs from the historical trapezium keyword mapping. Do not transfer a positional tuple between the APIs without translating it explicitly. The shared scalar formulas retain the accepted historical boundaries, including peak == right for the existing high triangular term.

Earlier v2 development snapshots named the plateau arguments plateau_start and plateau_end. The canonical names are now plateauStart and plateauEnd in Bell, Trapezoid, and MembershipFunction's read-only parameter mapping. Both constructors and direct family construction still accept the old keyword spellings at runtime; specifying an alias together with its canonical spelling is rejected. Positional order, parameter meaning and numerical results are unchanged. New code and static typing use the canonical camelCase names.

Fuzzy sets

Historical construction combines a membership object, a mutable name, and a tuple historically called supportSet:

from fuzzyroutines.FuzzyRoutines import FuzzySet, MFunction

membershipFunction = MFunction("triangle", a=0.0, b=1.0, c=0.5)
fuzzySet = FuzzySet(
    membershipFunction,
    supportSet=(0.0, 1.0),
    linguisticName="Medium",
)

For new set algebra, declare the universe separately and pass a membership callable:

from fuzzyroutines import (
    Complement,
    ContinuousUniverse,
    NegationPolicy,
    ScalarFuzzySet,
)

universe = ContinuousUniverse(0.0, 1.0, leftClosed=True, rightClosed=True)
membershipFunction = Triangle(left=0.0, peak=0.5, right=1.0)
fuzzySet = ScalarFuzzySet(universe, membershipFunction)
complement = Complement(fuzzySet, NegationPolicy("standard"))

assert complement.Membership(0.25) == 0.5

ScalarFuzzySet has no linguistic-name field and no numerical integration interval. IntegrationDomain is a separate operational value and is not mathematical support.

Scales

Continue to use the protected historical classes:

from fuzzyroutines.FuzzyRoutines import UniversalFuzzyScale

scale = UniversalFuzzyScale()
level = scale.Fuzzy(0.5)
assert level["name"] == "Med"

The modern API can represent names, fuzzy sets, and explicit term order without silently inheriting the historical dictionary shape:

from fuzzyroutines import FuzzificationPolicy, LinguisticScale, LinguisticTerm

modernScale = LinguisticScale((LinguisticTerm("Medium", fuzzySet),))
term = modernScale.GetTermByName("medium", exactMatching=False)
result = modernScale.Fuzzify(
    0.5,
    FuzzificationPolicy(tiePolicy="last", minimumConfidence=0.05),
)

The modern lookup matches only complete names. Its default mode is exact and case-sensitive; exactMatching=False uses Unicode case-insensitive comparison. It does not perform fuzzy, prefix, or substring name matching. Modern Fuzzify() returns all ordered membership scores and the maximum score as confidence. Its policy makes the no-match threshold, tie tolerance, and first, last, or all tie selection explicit. Historical callers may keep FuzzyScale or UniversalFuzzyScale; tiePolicy="last" provides the modern equivalent of the historical later-winner rule without changing Fuzzy().

Defuzzification

Existing code may continue to use the recalculating compatibility entry point:

from fuzzyroutines.FuzzyRoutines import FuzzySet, MFunction

membershipFunction = MFunction("triangle", a=0.0, b=1.0, c=0.5)
fuzzySet = FuzzySet(membershipFunction, supportSet=(0.0, 1.0))
centroid = fuzzySet.Defuz()

Defuz() now uses the modern analytical/adaptive strategy and ignores the retained compatibility attribute MFunction.accuracy. The historical supportSet tuple is a finite numerical integration interval, not exact positive support. New code can express the same operation explicitly:

from fuzzyroutines import Centroid, ContinuousUniverse, IntegrationDomain, ScalarFuzzySet

integrationDomain = IntegrationDomain.FromLegacyInterval(fuzzySet.supportSet)
modernSet = ScalarFuzzySet(ContinuousUniverse(), membershipFunction.mju)
centroid = Centroid(modernSet, integrationDomain)

See Centroid defuzzification for analytical families, adaptive tolerances, zero-area behavior, and convergence failure.

Executable examples

Both examples import only public package entry points and contain no source tree path manipulation:

python examples/migration/historical_compatibility.py
python examples/migration/modern_supported.py
  • historical_compatibility.py exercises all five historical areas.
  • modern_supported.py exercises explicit operator policies and immutable fuzzy sets while clearly using the focused immutable membership factory without importing the historical module.

The example tests execute each script from a temporary working directory. The package workflow independently installs the wheel and source distribution, removes PYTHONPATH, proves the import origin is inside the clean environment, and runs the same scripts through the shell-visible entry points. See Executable Tests, Tools, Benchmarks, and Examples for the complete artifact and exit-code contract.