Add convertions and CaseIterable helpers

This commit is contained in:
Alexander Ignatov 2021-12-30 01:23:48 +02:00
parent f0dee409b0
commit f7dcd8bcdb
5 changed files with 79 additions and 1 deletions

View File

@ -27,3 +27,9 @@ extension GeneralizedModusPonens: FuzzySet {
composition[element]
}
}
extension GeneralizedModusPonens: AnyFuzzySetRepresentable {
public func eraseToAnyFuzzySet() -> AnyFuzzySet<V> {
.init { composition[$0] }
}
}

View File

@ -26,7 +26,21 @@ public struct FuzzyRelationsComposition<U, V, W, Seq: Sequence> where Seq.Elemen
}
}
public extension FuzzyRelationsComposition where V: CaseIterable, Seq == V.AllCases {
init(
_ relationUV: BinaryFuzzyRelation<U, V>,
_ relationVW: BinaryFuzzyRelation<V, W>,
method: CompositionMethod = .maxmin
) {
self.relationUV = relationUV
self.relationVW = relationVW
self.sequence = V.allCases
self.method = method
}
}
extension FuzzyRelationsComposition: FuzzySet {
/// - Complexity: O(*n*) where *n* is the number of elements in `self.sequence` (number of elements of `V` to be iterated over via `Seq`)
public func grade(forElement element: (U, W)) -> Grade {
let u = element.0
let w = element.1

View File

@ -12,6 +12,7 @@ public struct FuzzySetComposition<U, V, Seq: Sequence> where Seq.Element == U {
}
extension FuzzySetComposition: FuzzySet {
/// - Complexity: O(*n*) where *n* is the number of elements in `self.set.sequence` (number of elements of `V` to be iterated over via `Seq`)
public func grade(forElement element: V) -> Grade {
set.map {
min($0.grade, relation[$0.element, element])

View File

@ -26,6 +26,18 @@ public struct IterableFuzzySet<Universe, S: Sequence> where S.Element == Univers
}
}
public extension IterableFuzzySet where Universe: CaseIterable, S == Universe.AllCases {
init(membershipFunction: MembershipFunction<Universe>) {
self.sequence = Universe.allCases
self.function = membershipFunction
}
init(membershipFunction: @escaping MembershipFunction<Universe>.FunctionType) {
self.sequence = Universe.allCases
self.function = .init(membershipFunction)
}
}
// MARK: - Fuzzy set
extension IterableFuzzySet: FuzzySet {
@ -102,16 +114,34 @@ public extension AnyFuzzySet {
}
}
public extension AnyFuzzySet where Universe: CaseIterable {
func makeIterable() -> IterableFuzzySet<Universe, Universe.AllCases> {
.init(Universe.allCases, membershipFunction: membershipFunction)
}
}
public extension DiscreteMutableFuzzySet {
func makeIterable() -> IterableFuzzySet<Universe, Dictionary<Universe, Grade>.Keys> {
.init(grades.keys, membershipFunction: .fromDictionary(grades))
}
func makeIterable<S: Sequence>(_ sequence: S) -> IterableFuzzySet<Universe, S> {
func makeIterable<S: Sequence>(over sequence: S) -> IterableFuzzySet<Universe, S> {
.init(sequence, membershipFunction: .init { self[$0] })
}
}
public extension DiscreteMutableFuzzySet where Universe: CaseIterable {
func makeIterable() -> IterableFuzzySet<Universe, Universe.AllCases> {
.init(Universe.allCases, membershipFunction: .fromDictionary(grades))
}
}
public extension IterableFuzzySet where Universe: Hashable {
func makeDiscreteMutable() -> DiscreteMutableFuzzySet<Universe> {
.init(.init(uniqueKeysWithValues: sequence.map { ($0, self[$0]) }))
}
}
// MARK: - Properties
public extension IterableFuzzySet {

View File

@ -47,6 +47,33 @@ class IterableFuzzySetTests: XCTestCase {
XCTAssertEqual(result, expected)
}
func test_initFromCaseIterableEnum_sequenceNotRequired() {
enum U: Int, CaseIterable {
case a, b, c, d, e, f, g, h, i, j, k
}
let sut = IterableFuzzySet { (u: U) in
Double(u.rawValue) / Double(U.allCases.count)
}
let sut2 = IterableFuzzySet(membershipFunction: MembershipFunction<U>.one)
XCTAssertEqual(Array(sut).map { $0.element }, U.allCases)
XCTAssertEqual(Array(sut2).map { $0.element }, U.allCases)
}
func test_initFromDiscreteMutableWhenCaseIterable_noAmbiguity() {
enum U: CaseIterable {
case a, b, c, d, e, f, g, h, i, j, k
}
let fs = DiscreteMutableFuzzySet(.init(uniqueKeysWithValues: U.allCases.map { ($0, 0.42) }))
let sut = fs.makeIterable()
XCTAssertEqual(Array(sut).map { $0.element }, U.allCases)
}
func test_alphaCut_allValuesAreBelowAlpha() {
let alpha = 0.5
let set = IterableFuzzySet(