Cover photo

FuzzyKit

Fuzzy sets and fuzzy logic theory implementations.

Made for Swift Swift Package Manager supported

Build & Test License

Example Usage

import FuzzyKit

enum Funding { case adequate, marginal, inadequate }
enum Staffing { case small, large }
enum Risk { case low, normal, high }

let funding: SimpleLinguisticVariable<Funding, AnyFuzzySet> = [
    .inadequate: .init(membershipFunction: .leftOpen(slopeStart: 15, slopeEnd: 35)),
    .marginal: .init(membershipFunction: .triangular(minimum: 21, peak: 41, maximum: 61)),
    .adequate: .init(membershipFunction: .rightOpen(slopeStart: 55, slopeEnd: 75)),
]

let staffing: SimpleLinguisticVariable<Staffing, AnyFuzzySet> = [
    .small: .init(membershipFunction: .leftOpen(slopeStart: 29, slopeEnd: 69)),
    .large: .init(membershipFunction: .rightOpen(slopeStart: 37, slopeEnd: 77)),
]

let risk: SimpleLinguisticVariable<Risk, AnyFuzzySet> = [
    .low: .init(membershipFunction: .leftOpen(slopeStart: 20, slopeEnd: 40)),
    .normal: .init(membershipFunction: .triangular(minimum: 20, peak: 50, maximum: 80)),
    .high: .init(membershipFunction: .rightOpen(slopeStart: 60, slopeEnd: 80)),
]

let Ø = AnyFuzzySet<Double>.empty

let ruleBase = FuzzyRuleBase {
    funding.is(.adequate) || staffing.is(.small) --> risk.is(.low)
    funding.is(.marginal) && staffing.is(.large) --> risk.is(.normal)
    funding.is(.inadequate) || Ø --> risk.is(.high)
}

let flc = FuzzyLogicController(rules: ruleBase, settings: .init(implication: .mamdani))

flc.consequenceGrade(for: 50, usingSingletonFact: (8.8, 42))  // result is 0.675

Modules

Using the Swift Package Manager, don’t forget to add the package as a dependency to your Package.swift file:

dependencies: [
+   .package(url: "https://github.com/allexks/FuzzyKit", .upToNextMajor(from: "0.1.0")),
],

To be able to use everything from this package, you can import everything at once using this helper module:

.target(
    name: "...",
    dependencies: [
+       .product(name: "FuzzyKit", package: "FuzzyKit"),
    ]
),
import FuzzyKit

Or alternatively, import only the specific modules needed:

.target(
    name: "...",
    dependencies: [
+       .product(name: "FuzzySets", package: "FuzzyKit"),
+       .product(name: "FuzzyNumbers", package: "FuzzyKit"),
+       .product(name: "FuzzyRelations", package: "FuzzyKit"),
+       .product(name: "FuzzyLogic", package: "FuzzyKit"),
    ]
),
import FuzzySets
import FuzzyNumbers
import FuzzyRelations
import FuzzyLogic

API Reference

API Reference automatically collected with jazzy is published here with each new release.

FuzzySets Module

protocol FuzzySet

This abstraction requires a fuzzy set to provide a grade(forElement:) method which accepts a parameter of an associatedtype Universe and returns its membership Grade in the set. There are 3 provided concrete implementations in this module:

  1. struct AnyFuzzySet - allows type erasure. It only stores a MembershipFunction and has non-mutable methods.

  2. struct IterableFuzzySet - stores a MembershipFunction as well as a Sequence of elements of the associated type Universe. Implements Sequence so that it can easily be iterated over them. The elements of the iteration over an IterableFuzzySet are structs containing grade and element properties. It has non-mutable methods only. Includes support, core and height computed properties.

  3. struct DiscreteMutableFuzzySet - it is “discrete” because it doesn’t stores a MembershipFunction but instead keeps its elements and their grade in a Dictionary, and it is “mutable” because it contains mutable equivalents of all other methods that operate over the set (including subscript). A default value of 0 is returned for the grade of an element that is not in the dictionary (a different default value can be provided as well). Includes support, core and height computed properties. A bonus feature is its debug print using Zadeh’s notation.

Convertions between the 3 types are easy and possible using the eraseToAnyFuzzySet, makeIterable and makeDiscreteMutable methods defined on them.

protocol FuzzySetOperations

All 3 concrete types implement it. It requires the following methods that operate on fuzzy sets:

  • alphaCut(_:alpha:)

  • complement(method:)

  • intersection(_:method:)

  • union(_:method:)

  • difference(_:method:)

  • symmetricDifference(_:method:)

  • power(_:n:)

  • appliedCustomFunction(_:function:)

License

MIT

FOSSA Status