1 /**
2  *
3  *   Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(_at_LIP6) & Christophe GONZALES(_at_AMU)
4  *   info_at_agrum_dot_org
5  *
6  *  This library is free software: you can redistribute it and/or modify
7  *  it under the terms of the GNU Lesser General Public License as published by
8  *  the Free Software Foundation, either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public License
17  *  along with this library.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 
22 #include <gumtest/AgrumTestSuite.h>
23 #include <gumtest/testsuite_utils.h>
24 #include <ressources/include/countedAlloc.h>
25 #include <ressources/include/poolAlloc.h>
26 #include <iostream>
27 
28 #include <agrum/tools/core/thread.h>
29 #include <agrum/tools/database/DBTranslator4IntegerVariable.h>
30 
31 namespace gum_tests {
32 
33   class DBTranslator4IntegerVariableTestSuite: public CxxTest::TestSuite {
34     public:
test_trans1()35     void test_trans1() {
36       gum::IntegerVariable var("X1", "");
37       var.addValue(1);
38       var.addValue(3);
39       var.addValue(10);
40       var.addValue(12);
41 
42       gum::learning::DBTranslator4IntegerVariable< DebugCountedAlloc > translator(var);
43       TS_ASSERT(translator.isLossless())
44       TS_GUM_ASSERT_THROWS_NOTHING(translator.translate("1"));
45       TS_ASSERT_EQUALS(translator.translate("1").discr_val, (std::size_t)0)
46       TS_ASSERT_EQUALS(translator.translate("3").discr_val, (std::size_t)1)
47       TS_ASSERT_EQUALS(translator.translate("10").discr_val, (std::size_t)2)
48       TS_ASSERT_THROWS(translator.translate("0"), gum::UnknownLabelInDatabase)
49       TS_ASSERT_THROWS(translator.translate("11"), gum::UnknownLabelInDatabase)
50       TS_ASSERT_THROWS(translator.translate("aaa"), gum::TypeError)
51 
52       TS_ASSERT_EQUALS(translator.missingValue().discr_val,
53                        std::numeric_limits< std::size_t >::max());
54 
55       TS_GUM_ASSERT_THROWS_NOTHING(translator.translate("12"));
56       TS_ASSERT(translator.translateBack(gum::learning::DBTranslatedValue{std::size_t{0}}) == "1")
57       TS_ASSERT(translator.translateBack(gum::learning::DBTranslatedValue{std::size_t{1}}) == "3")
58 
59       const auto& tr_var = *(translator.variable());
60       int         good   = 1;
61       try {
62         const gum::IntegerVariable& xvar_discr
63            = dynamic_cast< const gum::IntegerVariable& >(tr_var);
64         TS_ASSERT_EQUALS(xvar_discr.domainSize(), (gum::Size)4)
65         TS_ASSERT_EQUALS(xvar_discr.label(0), "1")
66         TS_ASSERT_EQUALS(xvar_discr.label(1), "3")
67         TS_ASSERT_EQUALS(xvar_discr.label(2), "10")
68         TS_ASSERT_EQUALS(xvar_discr.label(3), "12")
69       } catch (std::bad_cast&) { good = 0; }
70       TS_ASSERT_EQUALS(good, 1)
71 
72       std::vector< std::string >                    missing{"?", "N/A", "???"};
73       gum::learning::DBTranslator4IntegerVariable<> translator2(var, missing);
74       TS_GUM_ASSERT_THROWS_NOTHING(translator2.translate("1"));
75       TS_GUM_ASSERT_THROWS_NOTHING(translator2.translate("12"));
76       TS_ASSERT_EQUALS(translator2.translate("1").discr_val, (std::size_t)0)
77       TS_ASSERT_EQUALS(translator2.translate("3").discr_val, (std::size_t)1)
78       TS_ASSERT_EQUALS(translator2.translate("N/A").discr_val,
79                        std::numeric_limits< std::size_t >::max());
80       TS_ASSERT_EQUALS(translator2.translate("?").discr_val,
81                        std::numeric_limits< std::size_t >::max());
82       TS_ASSERT_EQUALS(translator2.translate("???").discr_val,
83                        std::numeric_limits< std::size_t >::max());
84       TS_ASSERT_THROWS(translator2.translate("??"), gum::TypeError)
85       TS_ASSERT_EQUALS(translator.translateBack(gum::learning::DBTranslatedValue{std::size_t{0}}),
86                        "1");
87       TS_ASSERT_EQUALS(translator.translateBack(gum::learning::DBTranslatedValue{std::size_t{2}}),
88                        "10");
89 
90       gum::learning::DBTranslator4IntegerVariable< DebugCountedAlloc > translator3(var, missing, 4);
91       TS_GUM_ASSERT_THROWS_NOTHING(translator3.translate("1"));
92       TS_GUM_ASSERT_THROWS_NOTHING(translator3.translate("10"));
93       TS_ASSERT_EQUALS(translator3.translate("1").discr_val, (std::size_t)0)
94       TS_ASSERT_EQUALS(translator3.translate("3").discr_val, (std::size_t)1)
95       TS_ASSERT_EQUALS(translator3.translate("N/A").discr_val,
96                        std::numeric_limits< std::size_t >::max());
97       TS_ASSERT_EQUALS(translator3.translate("?").discr_val,
98                        std::numeric_limits< std::size_t >::max());
99       TS_ASSERT_EQUALS(translator3.translate("???").discr_val,
100                        std::numeric_limits< std::size_t >::max());
101       TS_ASSERT_THROWS(translator3.translate("??"), gum::TypeError)
102       TS_ASSERT_THROWS(translator3.translate("a"), gum::TypeError)
103 
104       TS_ASSERT(translator3.translateBack(gum::learning::DBTranslatedValue{std::size_t{0}}) == "1")
105       TS_ASSERT(translator3.translateBack(gum::learning::DBTranslatedValue{std::size_t{1}}) == "3")
106       TS_ASSERT_THROWS(translator3.translateBack(gum::learning::DBTranslatedValue{std::size_t{4}}),
107                        gum::UnknownLabelInDatabase);
108       TS_ASSERT_EQUALS(translator3.translateBack(gum::learning::DBTranslatedValue{
109                           std::numeric_limits< std::size_t >::max()}),
110                        "?");
111 
112       TS_ASSERT_EQUALS(translator3.domainSize(), (gum::Size)4)
113 
114       TS_ASSERT_THROWS(gum::learning::DBTranslator4IntegerVariable<> translator4(var, missing, 1),
115                        gum::SizeError);
116 
117       TS_ASSERT_EQUALS(translator3.variable()->toString(), "X1:Integer(<1,3,10,12>)")
118       TS_ASSERT_EQUALS(translator3.domainSize(), (gum::Size)4)
119       TS_ASSERT(!translator3.hasEditableDictionary())
120       translator3.setEditableDictionaryMode(true);
121       TS_ASSERT(!translator3.hasEditableDictionary())
122       TS_ASSERT(!translator3.needsReordering())
123       TS_ASSERT(translator3.reorder().empty())
124     }
125 
126 
test_trans2()127     void test_trans2() {
128       {
129         gum::IntegerVariable var("X1", "");
130         var.addValue(1);
131         var.addValue(3);
132         var.addValue(10);
133         var.addValue(12);
134 
135         gum::learning::DBTranslator4IntegerVariable<> translator(var);
136         TS_ASSERT_EQUALS(translator.translate("1").discr_val, (std::size_t)0)
137         TS_ASSERT_EQUALS(translator.translate("12").discr_val, (std::size_t)3)
138         TS_ASSERT_EQUALS(translator.translateBack(gum::learning::DBTranslatedValue{std::size_t{0}}),
139                          "1");
140         TS_ASSERT_EQUALS(translator.translateBack(gum::learning::DBTranslatedValue{std::size_t{1}}),
141                          "3");
142         TS_ASSERT_EQUALS(translator.translateBack(gum::learning::DBTranslatedValue{std::size_t{2}}),
143                          "10");
144         TS_ASSERT_EQUALS(translator.variable()->toString(), "X1:Integer(<1,3,10,12>)")
145 
146         TS_ASSERT_EQUALS(
147            translator.translate(translator.translateBack(translator.translate("1"))).discr_val,
148            (std::size_t)0);
149 
150         gum::IntegerVariable var2("X2", "");
151         var2.addValue(1);
152         var2.addValue(2);
153         var2.addValue(3);
154         var2.addValue(4);
155 
156         gum::learning::DBTranslator4IntegerVariable< DebugCountedAlloc > translator2(var2);
157         TS_ASSERT_EQUALS(translator2.translate("1").discr_val, (std::size_t)0)
158         TS_ASSERT_EQUALS(translator2.translate("2").discr_val, (std::size_t)1)
159         TS_ASSERT_EQUALS(translator2.translate("4").discr_val, (std::size_t)3)
160         TS_ASSERT_EQUALS(
161            translator2.translateBack(gum::learning::DBTranslatedValue{std::size_t{0}}),
162            "1");
163         TS_ASSERT_EQUALS(
164            translator2.translateBack(gum::learning::DBTranslatedValue{std::size_t{1}}),
165            "2");
166         TS_ASSERT_EQUALS(
167            translator2.translateBack(gum::learning::DBTranslatedValue{std::size_t{2}}),
168            "3");
169         TS_ASSERT_EQUALS(translator2.variable()->toString(), "X2:Integer(<1,2,3,4>)")
170 
171         gum::learning::DBTranslator4IntegerVariable<> translator3(translator);
172         TS_ASSERT_EQUALS(translator3.translate("1").discr_val, (std::size_t)0)
173         TS_ASSERT_EQUALS(translator3.translate("10").discr_val, (std::size_t)2)
174         TS_ASSERT_EQUALS(translator3.translate("12").discr_val, (std::size_t)3)
175         TS_ASSERT_EQUALS(
176            translator3.translateBack(gum::learning::DBTranslatedValue{std::size_t{0}}),
177            "1");
178         TS_ASSERT_EQUALS(
179            translator3.translateBack(gum::learning::DBTranslatedValue{std::size_t{1}}),
180            "3");
181         TS_ASSERT_EQUALS(
182            translator3.translateBack(gum::learning::DBTranslatedValue{std::size_t{2}}),
183            "10");
184         TS_ASSERT_EQUALS(translator3.variable()->toString(), "X1:Integer(<1,3,10,12>)")
185 
186         gum::learning::DBTranslator4IntegerVariable< DebugCountedAlloc > translator4(translator2);
187         TS_ASSERT_EQUALS(translator4.translate("1").discr_val, (std::size_t)0)
188         TS_ASSERT_EQUALS(translator4.translate("2").discr_val, (std::size_t)1)
189         TS_ASSERT_EQUALS(translator4.translate("4").discr_val, (std::size_t)3)
190         TS_ASSERT_EQUALS(
191            translator4.translateBack(gum::learning::DBTranslatedValue{std::size_t{0}}),
192            "1");
193         TS_ASSERT_EQUALS(
194            translator4.translateBack(gum::learning::DBTranslatedValue{std::size_t{1}}),
195            "2");
196         TS_ASSERT_EQUALS(
197            translator4.translateBack(gum::learning::DBTranslatedValue{std::size_t{2}}),
198            "3");
199         TS_ASSERT_EQUALS(translator4.variable()->toString(), "X2:Integer(<1,2,3,4>)")
200 
201         gum::learning::DBTranslator4IntegerVariable<> translator5(std::move(translator3));
202         TS_ASSERT_EQUALS(translator5.translate("1").discr_val, (std::size_t)0)
203         TS_ASSERT_EQUALS(translator5.translate("10").discr_val, (std::size_t)2)
204         TS_ASSERT_EQUALS(translator5.translate("12").discr_val, (std::size_t)3)
205         TS_ASSERT_EQUALS(
206            translator5.translateBack(gum::learning::DBTranslatedValue{std::size_t{0}}),
207            "1");
208         TS_ASSERT_EQUALS(
209            translator5.translateBack(gum::learning::DBTranslatedValue{std::size_t{1}}),
210            "3");
211         TS_ASSERT_EQUALS(
212            translator5.translateBack(gum::learning::DBTranslatedValue{std::size_t{2}}),
213            "10");
214         TS_ASSERT_EQUALS(translator5.variable()->toString(), "X1:Integer(<1,3,10,12>)")
215 
216         gum::learning::DBTranslator4IntegerVariable< DebugCountedAlloc > translator6(
217            std::move(translator4));
218         TS_ASSERT_EQUALS(translator6.translate("1").discr_val, (std::size_t)0)
219         TS_ASSERT_EQUALS(translator6.translate("2").discr_val, (std::size_t)1)
220         TS_ASSERT_EQUALS(translator6.translate("4").discr_val, (std::size_t)3)
221         TS_ASSERT_EQUALS(
222            translator6.translateBack(gum::learning::DBTranslatedValue{std::size_t{0}}),
223            "1");
224         TS_ASSERT_EQUALS(
225            translator6.translateBack(gum::learning::DBTranslatedValue{std::size_t{1}}),
226            "2");
227         TS_ASSERT_EQUALS(
228            translator6.translateBack(gum::learning::DBTranslatedValue{std::size_t{2}}),
229            "3");
230         TS_ASSERT_EQUALS(translator6.variable()->toString(), "X2:Integer(<1,2,3,4>)")
231 
232         gum::learning::DBTranslator4IntegerVariable< DebugCountedAlloc >* translator7
233            = translator6.clone();
234         TS_ASSERT_EQUALS(translator7->translate("1").discr_val, (std::size_t)0)
235         TS_ASSERT_EQUALS(translator7->translate("2").discr_val, (std::size_t)1)
236         TS_ASSERT_EQUALS(translator7->translate("4").discr_val, (std::size_t)3)
237         TS_ASSERT_EQUALS(
238            translator7->translateBack(gum::learning::DBTranslatedValue{std::size_t{0}}),
239            "1");
240         TS_ASSERT_EQUALS(
241            translator7->translateBack(gum::learning::DBTranslatedValue{std::size_t{1}}),
242            "2");
243         TS_ASSERT_EQUALS(
244            translator7->translateBack(gum::learning::DBTranslatedValue{std::size_t{2}}),
245            "3");
246         TS_ASSERT_EQUALS(translator7->variable()->toString(), "X2:Integer(<1,2,3,4>)")
247 
248         DebugCountedAlloc< gum::learning::DBTranslator4IntegerVariable< DebugCountedAlloc > >
249            allocator(translator7->getAllocator());
250         allocator.destroy(translator7);
251         allocator.deallocate(translator7, 1);
252 
253         gum::learning::DBTranslator4IntegerVariable< DebugCountedAlloc > translator8(var);
254         translator8 = translator6;
255         TS_ASSERT_EQUALS(translator8.translate("1").discr_val, (std::size_t)0)
256         TS_ASSERT_EQUALS(translator8.translate("2").discr_val, (std::size_t)1)
257         TS_ASSERT_EQUALS(translator8.translate("4").discr_val, (std::size_t)3)
258         TS_ASSERT_EQUALS(
259            translator8.translateBack(gum::learning::DBTranslatedValue{std::size_t{0}}),
260            "1");
261         TS_ASSERT_EQUALS(
262            translator8.translateBack(gum::learning::DBTranslatedValue{std::size_t{1}}),
263            "2");
264         TS_ASSERT_EQUALS(
265            translator8.translateBack(gum::learning::DBTranslatedValue{std::size_t{2}}),
266            "3");
267         TS_ASSERT_EQUALS(translator8.variable()->toString(), "X2:Integer(<1,2,3,4>)")
268 
269         gum::learning::DBTranslator4IntegerVariable< DebugCountedAlloc > translator8bis(var);
270         gum::learning::DBTranslator4IntegerVariable< DebugCountedAlloc > translator9(var2);
271         translator9 = translator8bis;
272         TS_ASSERT_EQUALS(translator9.translate("1").discr_val, (std::size_t)0)
273         TS_ASSERT_EQUALS(translator9.translate("3").discr_val, (std::size_t)1)
274         TS_ASSERT_EQUALS(translator9.translate("10").discr_val, (std::size_t)2)
275         TS_ASSERT_EQUALS(
276            translator9.translateBack(gum::learning::DBTranslatedValue{std::size_t{0}}),
277            "1");
278         TS_ASSERT_EQUALS(
279            translator9.translateBack(gum::learning::DBTranslatedValue{std::size_t{1}}),
280            "3");
281         TS_ASSERT_EQUALS(
282            translator9.translateBack(gum::learning::DBTranslatedValue{std::size_t{2}}),
283            "10");
284         TS_ASSERT_EQUALS(translator9.variable()->toString(), "X1:Integer(<1,3,10,12>)")
285 
286         translator8 = std::move(translator9);
287         TS_ASSERT_EQUALS(translator8.translate("1").discr_val, (std::size_t)0)
288         TS_ASSERT_EQUALS(translator8.translate("3").discr_val, (std::size_t)1)
289         TS_ASSERT_EQUALS(translator8.translate("10").discr_val, (std::size_t)2)
290         TS_ASSERT_EQUALS(
291            translator8.translateBack(gum::learning::DBTranslatedValue{std::size_t{0}}),
292            "1");
293         TS_ASSERT_EQUALS(
294            translator8.translateBack(gum::learning::DBTranslatedValue{std::size_t{1}}),
295            "3");
296         TS_ASSERT_EQUALS(
297            translator8.translateBack(gum::learning::DBTranslatedValue{std::size_t{2}}),
298            "10");
299         TS_ASSERT_EQUALS(translator8.variable()->toString(), "X1:Integer(<1,3,10,12>)")
300       }
301 
302       TS_ASSERT_EQUALS(CountedAlloc::hasMemoryLeak(), false)
303     }
304   };
305 
306 } /* namespace gum_tests */
307