summaryrefslogtreecommitdiff
path: root/fuzzylite/test/hedge/HedgeFunctionTest.cpp
blob: dab70f5016a2a9cf95da4c6a4e6a959262cae6ac (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
 fuzzylite (R), a fuzzy logic control library in C++.
 Copyright (C) 2010-2017 FuzzyLite Limited. All rights reserved.
 Author: Juan Rada-Vilela, Ph.D. <jcrada@fuzzylite.com>

 This file is part of fuzzylite.

 fuzzylite is free software: you can redistribute it and/or modify it under
 the terms of the FuzzyLite License included with the software.

 You should have received a copy of the FuzzyLite License along with
 fuzzylite. If not, see <http://www.fuzzylite.com/license/>.

 fuzzylite is a registered trademark of FuzzyLite Limited.
 */

#include "test/catch.hpp"
#include "fl/Headers.h"

namespace fl {

    /**
     * Tests: hedge/HedgeFunction
     *
     * @author Juan Rada-Vilela, Ph.D.
     *
     */

    static std::string hedgeEngine() {
#ifdef FL_CPP98
        return "";
#else
        return R""(
Engine: Sugeno-Tip-Calculator
InputVariable: FoodQuality
  enabled: true
  range: 1.000 10.000
  lock-range: false
  term: Bad Trapezoid 0.000 1.000 3.000 7.000
  term: Good Trapezoid 3.000 7.000 10.000 11.000
InputVariable: Service
  enabled: true
  range: 1.000 10.000
  lock-range: false
  term: Bad Trapezoid 0.000 1.000 3.000 7.000
  term: Good Trapezoid 3.000 7.000 10.000 11.000
OutputVariable: CheapTip
  enabled: true
  range: 5.000 25.000
  lock-range: false
  aggregation: none
  defuzzifier: WeightedAverage TakagiSugeno
  default: nan
  lock-previous: false
  term: Low Constant 10.000
  term: Medium Constant 15.000
  term: High Constant 20.000
OutputVariable: AverageTip
  enabled: true
  range: 5.000 25.000
  lock-range: false
  aggregation: none
  defuzzifier: WeightedAverage TakagiSugeno
  default: nan
  lock-previous: false
  term: Low Constant 10.000
  term: Medium Constant 15.000
  term: High Constant 20.000
OutputVariable: GenerousTip
  enabled: true
  range: 5.000 25.000
  lock-range: false
  aggregation: none
  defuzzifier: WeightedAverage TakagiSugeno
  default: nan
  lock-previous: false
  term: Low Constant 10.000
  term: Medium Constant 15.000
  term: High Constant 20.000
RuleBlock:
  enabled: true
  conjunction: EinsteinProduct
  disjunction: none
  implication: none
  activation: General
  rule: if FoodQuality is extremely Bad and Service is extremely Bad then CheapTip is extremely Low and AverageTip is very Low and GenerousTip is Low
  rule: if FoodQuality is Good and Service is extremely Bad then CheapTip is Low and AverageTip is Low and GenerousTip is Medium
  rule: if FoodQuality is very Good and Service is very Bad then CheapTip is Low and AverageTip is Medium and GenerousTip is High
  rule: if FoodQuality is Bad and Service is Bad then CheapTip is Low and AverageTip is Low and GenerousTip is Medium
  rule: if FoodQuality is Good and Service is Bad then CheapTip is Low and AverageTip is Medium and GenerousTip is High
  rule: if FoodQuality is extremely Good and Service is Bad then CheapTip is Low and AverageTip is Medium and GenerousTip is very High
  rule: if FoodQuality is Bad and Service is Good then CheapTip is Low and AverageTip is Medium and GenerousTip is High
  rule: if FoodQuality is Good and Service is Good then CheapTip is Medium and AverageTip is Medium and GenerousTip is very High
  rule: if FoodQuality is very Bad and Service is very Good then CheapTip is Low and AverageTip is Medium and GenerousTip is High
  rule: if FoodQuality is very very Good and Service is very very Good then CheapTip is High and AverageTip is very High and GenerousTip is extremely High
)"";
#endif
    }

    static Hedge* myVeryConstructor() {
        return new HedgeFunction("x*x");
    }

    static Hedge* myExtraVeryConstructor() {
        return new HedgeFunction("x*x*x");
    }

    TEST_CASE("HedgeFunction x*x is equivalent to hedge Very", "[hedge][function]") {
#ifdef FL_CPP98
        FL_IUNUSED(&(hedgeEngine));
        FL_IUNUSED(&(myVeryConstructor));
        FL_IUNUSED(&(myExtraVeryConstructor));
        WARN("Test only runs with -DFL_CPP98=OFF");
        return;
#else
        std::string fllEngine = hedgeEngine();
        //Import using regular hedge very
        FL_unique_ptr<Engine> engine(FllImporter().fromString(fllEngine));
        std::string fldVery = FldExporter().toString(engine.get(), 1024);

        //Replace hedge very with a HedgeFunction(x*x)
        HedgeFactory* factory = FactoryManager::instance()->hedge();
        factory->registerConstructor("very", &(myVeryConstructor));
        //Import again with new HedgeFunction
        engine.reset(FllImporter().fromString(fllEngine));
        std::string anotherFld = FldExporter().toString(engine.get(), 1024);
        //Both must be equal
        CHECK(fldVery == anotherFld);

        //Replace very with a HedgeFunction(x*x*x)
        factory->registerConstructor("very", &(myExtraVeryConstructor));

        engine.reset(FllImporter().fromString(fllEngine));
        anotherFld = FldExporter().toString(engine.get(), 1024);

        //Must be different
        CHECK(fldVery != anotherFld);
#endif
    }

}