dlvhex
2.5.0
|
00001 /* dlvhex -- Answer-Set Programming with external interfaces. 00002 * Copyright (C) 2005, 2006, 2007 Roman Schindlauer 00003 * Copyright (C) 2006, 2007, 2008, 2009, 2010 Thomas Krennwallner 00004 * Copyright (C) 2009, 2010 Peter Schüller 00005 * 00006 * This file is part of dlvhex. 00007 * 00008 * dlvhex is free software; you can redistribute it and/or modify it 00009 * under the terms of the GNU Lesser General Public License as 00010 * published by the Free Software Foundation; either version 2.1 of 00011 * the License, or (at your option) any later version. 00012 * 00013 * dlvhex is distributed in the hope that it will be useful, but 00014 * WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 * Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License along with dlvhex; if not, write to the Free Software 00020 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 00021 * 02110-1301 USA. 00022 */ 00023 00031 #ifdef HAVE_CONFIG_H 00032 #include "config.h" 00033 #endif // HAVE_CONFIG_H 00034 00035 #include <boost/cstdint.hpp> 00036 #include "dlvhex2/ID.h" 00037 #include "dlvhex2/Term.h" 00038 #include "dlvhex2/Atoms.h" 00039 #include "dlvhex2/TermTable.h" 00040 #include "dlvhex2/OrdinaryAtomTable.h" 00041 #include "dlvhex2/BuiltinAtomTable.h" 00042 #include "dlvhex2/AggregateAtomTable.h" 00043 #include "dlvhex2/RuleTable.h" 00044 00045 #define BOOST_TEST_MODULE "TestTables" 00046 #include <boost/test/unit_test.hpp> 00047 00048 #include <iostream> 00049 00050 LOG_INIT(Logger::ERROR | Logger::WARNING) 00051 00052 DLVHEX_NAMESPACE_USE 00053 00054 BOOST_AUTO_TEST_CASE(testTermTable) 00055 { 00056 Term term_a(ID::MAINKIND_TERM | ID::SUBKIND_TERM_CONSTANT, "a"); 00057 std::string stra("a"); 00058 00059 Term term_b(ID::MAINKIND_TERM | ID::SUBKIND_TERM_CONSTANT, "b"); 00060 00061 Term term_hello(ID::MAINKIND_TERM | ID::SUBKIND_TERM_CONSTANT, "\"Hello World\""); 00062 std::string strhello("\"Hello World\""); 00063 00064 Term term_X(ID::MAINKIND_TERM | ID::SUBKIND_TERM_VARIABLE, "X"); 00065 00066 Term term_Y(ID::MAINKIND_TERM | ID::SUBKIND_TERM_VARIABLE, "Y"); 00067 00068 Term term_Z(ID::MAINKIND_TERM | ID::SUBKIND_TERM_VARIABLE | ID::PROPERTY_VAR_ANONYMOUS, "Z"); 00069 std::string strZ("Z"); 00070 00071 BOOST_CHECK_EQUAL(sizeof(ID), 8); 00072 00073 { 00074 TermTable stab; 00075 00076 BOOST_CHECK_EQUAL(ID_FAIL, stab.getIDByString(stra)); 00077 00078 ID ida = stab.storeAndGetID(term_a); 00079 BOOST_CHECK_EQUAL(sizeof(ida), 8); 00080 00081 BOOST_CHECK_EQUAL(ida.kind, stab.getByID(ida).kind); 00082 BOOST_CHECK_EQUAL(ida, stab.getIDByString(stra)); 00083 BOOST_CHECK_EQUAL(ida.address, 0); 00084 00085 LOG(INFO,"TermTable" << stab); 00086 } 00087 00088 { 00089 TermTable stab; 00090 00091 ID ida = stab.storeAndGetID(term_a); 00092 ID idX = stab.storeAndGetID(term_X); 00093 ID idb = stab.storeAndGetID(term_b); 00094 ID idY = stab.storeAndGetID(term_Y); 00095 ID idhello = stab.storeAndGetID(term_hello); 00096 ID idZ = stab.storeAndGetID(term_Z); 00097 00098 BOOST_CHECK_EQUAL(ida.address, 0); 00099 BOOST_CHECK_EQUAL(idX.address, 1); 00100 BOOST_CHECK_EQUAL(idb.address, 2); 00101 BOOST_CHECK_EQUAL(idY.address, 3); 00102 BOOST_CHECK_EQUAL(idhello.address, 4); 00103 BOOST_CHECK_EQUAL(idZ.address, 5); 00104 00105 BOOST_CHECK_EQUAL(ida.kind, term_a.kind); 00106 BOOST_CHECK_EQUAL(idX.kind, term_X.kind); 00107 BOOST_CHECK_EQUAL(idb.kind, term_b.kind); 00108 BOOST_CHECK_EQUAL(idY.kind, term_Y.kind); 00109 BOOST_CHECK_EQUAL(idhello.kind, term_hello.kind); 00110 BOOST_CHECK_EQUAL(idZ.kind, term_Z.kind); 00111 00112 ID getida = stab.getIDByString(stra); 00113 BOOST_CHECK_EQUAL(ida.kind, term_a.kind); 00114 BOOST_CHECK_EQUAL(ida.address, 0); 00115 00116 const Term& giterm_a = stab.getByID(ida); 00117 BOOST_CHECK_EQUAL(term_a.symbol, giterm_a.symbol); 00118 00119 ID getidhello = stab.getIDByString(strhello); 00120 BOOST_CHECK_EQUAL(idhello.kind, term_hello.kind); 00121 BOOST_CHECK_EQUAL(idhello.address, 4); 00122 00123 ID getidZ = stab.getIDByString(strZ); 00124 BOOST_CHECK_EQUAL(idZ.kind, term_Z.kind); 00125 BOOST_CHECK_EQUAL(idZ.address, 5); 00126 00127 const Term& giterm_X = stab.getByID(idX); 00128 BOOST_CHECK_EQUAL(idX.kind, giterm_X.kind); 00129 00130 const Term& giterm_hello = stab.getByID(idhello); 00131 BOOST_CHECK_EQUAL(term_hello.symbol, giterm_hello.symbol); 00132 00133 LOG(INFO,"TermTable" << stab); 00134 } 00135 } 00136 00137 BOOST_AUTO_TEST_CASE(testOrdinaryAtomTable) 00138 { 00139 Term term_a(ID::MAINKIND_TERM | ID::SUBKIND_TERM_CONSTANT, "a"); 00140 Term term_b(ID::MAINKIND_TERM | ID::SUBKIND_TERM_CONSTANT, "b"); 00141 Term term_hello(ID::MAINKIND_TERM | ID::SUBKIND_TERM_CONSTANT, "\"Hello World\""); 00142 Term term_X(ID::MAINKIND_TERM | ID::SUBKIND_TERM_VARIABLE, "X"); 00143 Term term_Y(ID::MAINKIND_TERM | ID::SUBKIND_TERM_VARIABLE, "Y"); 00144 00145 TermTable stab; 00146 ID ida = stab.storeAndGetID(term_a); 00147 ID idX = stab.storeAndGetID(term_X); 00148 ID idb = stab.storeAndGetID(term_b); 00149 ID idY = stab.storeAndGetID(term_Y); 00150 ID idhello = stab.storeAndGetID(term_hello); 00151 LOG(INFO,"TermTable" << stab); 00152 00153 Tuple tupb; tupb.push_back(idb); 00154 OrdinaryAtom atb(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, "b", tupb); 00155 #warning reenable true negation 00156 00157 Tuple tupab; tupab.push_back(ida); tupab.push_back(idb); 00158 OrdinaryAtom atab(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, "a(b)", tupab); 00159 Tuple tupaX; tupaX.push_back(ida); tupaX.push_back(idX); 00160 OrdinaryAtom ataX(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYN, "a(X)", tupaX); 00161 Tuple tupYhello; tupYhello.push_back(idY); tupYhello.push_back(idhello); 00162 OrdinaryAtom atYhello(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYN, "Y(\"Hello World\")", tupYhello); 00163 00164 { 00165 OrdinaryAtomTable oatab; 00166 00167 BOOST_CHECK_EQUAL(ID_FAIL, oatab.getIDByString("b")); 00168 00169 ID idatb = oatab.storeAndGetID(atb); 00170 00171 BOOST_CHECK_EQUAL(idatb.kind, oatab.getByID(idatb).kind); 00172 BOOST_CHECK_EQUAL(idatb, oatab.getIDByString("b")); 00173 BOOST_CHECK_EQUAL(idatb, oatab.getIDByTuple(tupb)); 00174 BOOST_CHECK_EQUAL(idatb.address, 0); 00175 00176 #warning reenable true negation 00177 00178 ID idatab = oatab.storeAndGetID(atab); 00179 ID idataX = oatab.storeAndGetID(ataX); 00180 ID idatYhello = oatab.storeAndGetID(atYhello); 00181 00182 LOG(INFO,"OrdinaryAtomTable" << oatab); 00183 } 00184 } 00185 00186 BOOST_AUTO_TEST_CASE(testBuiltinAtomTable) 00187 { 00188 ID idint(ID::MAINKIND_TERM | ID::SUBKIND_TERM_BUILTIN, ID::TERM_BUILTIN_INT); 00189 ID idmul(ID::MAINKIND_TERM | ID::SUBKIND_TERM_BUILTIN, ID::TERM_BUILTIN_MUL); 00190 Term term_a(ID::MAINKIND_TERM | ID::SUBKIND_TERM_CONSTANT, "a"); 00191 Term term_X(ID::MAINKIND_TERM | ID::SUBKIND_TERM_VARIABLE, "X"); 00192 Term term_Y(ID::MAINKIND_TERM | ID::SUBKIND_TERM_VARIABLE, "Y"); 00193 00194 TermTable ttab; 00195 ID ida = ttab.storeAndGetID(term_a); 00196 ID idX = ttab.storeAndGetID(term_X); 00197 ID idY = ttab.storeAndGetID(term_Y); 00198 LOG(INFO,"TermTable" << ttab); 00199 00200 // #int(X) 00201 Tuple tupintX; tupintX.push_back(idint); tupintX.push_back(idX); 00202 BuiltinAtom atintX(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_BUILTIN, tupintX); 00203 00204 // *(a,X,Y) or a*X=Y 00205 Tuple tupmulaXY; tupmulaXY.push_back(idmul); 00206 tupmulaXY.push_back(ida); tupmulaXY.push_back(idX); tupmulaXY.push_back(idY); 00207 BuiltinAtom atmulaXY(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_BUILTIN, tupmulaXY); 00208 00209 { 00210 BuiltinAtomTable batab; 00211 00212 ID idintX = batab.storeAndGetID(atintX); 00213 00214 BOOST_CHECK_EQUAL(idintX.kind, batab.getByID(idintX).kind); 00215 BOOST_CHECK_EQUAL(idintX.address, 0); 00216 00217 BOOST_CHECK(batab.getByID(idintX).tuple == tupintX); 00218 00219 ID idmulaXY = batab.storeAndGetID(atmulaXY); 00220 00221 LOG(INFO,"BuiltinAtomTable" << batab); 00222 } 00223 } 00224 00225 BOOST_AUTO_TEST_CASE(testAggregateAtomTable) 00226 { 00227 // terms 00228 ID idlt(ID::MAINKIND_TERM | ID::SUBKIND_TERM_BUILTIN, ID::TERM_BUILTIN_LT); 00229 ID idsum(ID::MAINKIND_TERM | ID::SUBKIND_TERM_BUILTIN, ID::TERM_BUILTIN_AGGSUM); 00230 00231 Term term_a(ID::MAINKIND_TERM | ID::SUBKIND_TERM_CONSTANT, "a"); 00232 Term term_X(ID::MAINKIND_TERM | ID::SUBKIND_TERM_VARIABLE, "X"); 00233 Term term_Y(ID::MAINKIND_TERM | ID::SUBKIND_TERM_VARIABLE, "Y"); 00234 00235 TermTable ttab; 00236 ID ida = ttab.storeAndGetID(term_a); 00237 ID idX = ttab.storeAndGetID(term_X); 00238 ID idY = ttab.storeAndGetID(term_Y); 00239 LOG(INFO,"TermTable" << ttab); 00240 00241 // ordinary atoms 00242 Tuple tupaXY; tupaXY.push_back(ida); tupaXY.push_back(idX); tupaXY.push_back(idY); 00243 OrdinaryAtom ataXY(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYN, "a(X,Y)", tupaXY); 00244 00245 OrdinaryAtomTable oatab; 00246 ID idaXY = oatab.storeAndGetID(ataXY); 00247 LOG(INFO,"OrdinaryAtomTable" << oatab); 00248 00249 // a <= #sum{ X, Y: a(X,Y) } 00250 Tuple tupext; 00251 tupext.push_back(ida); tupext.push_back(idlt); 00252 tupext.push_back(idsum); 00253 tupext.push_back(ID_FAIL); tupext.push_back(ID_FAIL); 00254 00255 Tuple tupvars; 00256 tupvars.push_back(idX); tupvars.push_back(idY); 00257 00258 Tuple tupatoms; 00259 tupatoms.push_back(idaXY); 00260 00261 AggregateAtom at(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_AGGREGATE, tupext, tupvars, tupatoms); 00262 00263 { 00264 AggregateAtomTable aatab; 00265 00266 ID id = aatab.storeAndGetID(at); 00267 00268 BOOST_CHECK_EQUAL(id.kind, aatab.getByID(id).kind); 00269 BOOST_CHECK_EQUAL(id.address, 0); 00270 00271 BOOST_CHECK(aatab.getByID(id).tuple == tupext); 00272 BOOST_CHECK(aatab.getByID(id).variables == tupvars); 00273 BOOST_CHECK(aatab.getByID(id).literals == tupatoms); 00274 00275 LOG(INFO,"AggregateAtomTable" << aatab); 00276 } 00277 } 00278 00279 #warning TODO testExternalAtomTable 00280 00281 BOOST_AUTO_TEST_CASE(testRuleTable) 00282 { 00283 // terms 00284 Term term_a(ID::MAINKIND_TERM | ID::SUBKIND_TERM_CONSTANT, "a"); 00285 Term term_b(ID::MAINKIND_TERM | ID::SUBKIND_TERM_CONSTANT, "b"); 00286 Term term_hello(ID::MAINKIND_TERM | ID::SUBKIND_TERM_CONSTANT, "\"Hello World\""); 00287 Term term_X(ID::MAINKIND_TERM | ID::SUBKIND_TERM_VARIABLE, "X"); 00288 Term term_Y(ID::MAINKIND_TERM | ID::SUBKIND_TERM_VARIABLE, "Y"); 00289 00290 TermTable stab; 00291 ID ida = stab.storeAndGetID(term_a); 00292 ID idX = stab.storeAndGetID(term_X); 00293 ID idb = stab.storeAndGetID(term_b); 00294 ID idY = stab.storeAndGetID(term_Y); 00295 ID idhello = stab.storeAndGetID(term_hello); 00296 LOG(INFO,"TermTable" << stab); 00297 00298 // ordinary atoms 00299 Tuple tupb; tupb.push_back(idb); 00300 OrdinaryAtom atb(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, "b", tupb); 00301 Tuple tupab; tupab.push_back(ida); tupab.push_back(idb); 00302 OrdinaryAtom atab(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYG, "a(b)", tupab); 00303 Tuple tupaX; tupaX.push_back(ida); tupaX.push_back(idX); 00304 OrdinaryAtom ataX(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYN, "a(X)", tupaX); 00305 Tuple tupYhello; tupYhello.push_back(idY); tupYhello.push_back(idhello); 00306 OrdinaryAtom atYhello(ID::MAINKIND_ATOM | ID::SUBKIND_ATOM_ORDINARYN, "Y(\"Hello World\")", tupYhello); 00307 00308 OrdinaryAtomTable oatab; 00309 ID idatb = oatab.storeAndGetID(atb); 00310 ID idatab = oatab.storeAndGetID(atab); 00311 ID idataX = oatab.storeAndGetID(ataX); 00312 ID idatYhello = oatab.storeAndGetID(atYhello); 00313 LOG(INFO,"OrdinaryAtomTable" << oatab); 00314 00315 // rules 00316 Tuple empty; 00317 00318 // disjunctive fact "b v a(b)" 00319 Tuple tupborab; 00320 tupborab.push_back(idatb); tupborab.push_back(idatab); 00321 Rule rule1(ID::MAINKIND_RULE | ID::SUBKIND_RULE_REGULAR | ID::PROPERTY_RULE_DISJ, tupborab, empty); 00322 00323 // regular rule "b :- a(X)" 00324 Tuple tupb2; tupb2.push_back(idatb); 00325 Tuple tupaX2; tupaX2.push_back(idataX); 00326 Rule rule2(ID::MAINKIND_RULE | ID::SUBKIND_RULE_REGULAR, tupb2, tupaX2); 00327 00328 // constraint ":- a(b)" 00329 Tuple tupab2; tupab2.push_back(idatab); 00330 Rule rule3(ID::MAINKIND_RULE | ID::SUBKIND_RULE_CONSTRAINT, empty, tupab2); 00331 00332 // weak constraint ":~ b, a(X). [3,X]" 00333 Tuple tupbaX; tupbaX.push_back(idatb); tupbaX.push_back(idataX); 00334 Tuple wv; 00335 wv.push_back(ID_FAIL); // DLV-style weak constraint 00336 Rule rule4(ID::MAINKIND_RULE | ID::SUBKIND_RULE_WEAKCONSTRAINT, 00337 empty, tupbaX, ID(ID::MAINKIND_TERM | ID::SUBKIND_TERM_INTEGER, 3), idX, wv); 00338 00339 { 00340 RuleTable rtab; 00341 00342 ID id1 = rtab.storeAndGetID(rule1); 00343 BOOST_CHECK_EQUAL(id1.kind, rtab.getByID(id1).kind); 00344 BOOST_CHECK_EQUAL(id1.address, 0); 00345 BOOST_CHECK(rtab.getByID(id1).head == tupborab); 00346 BOOST_CHECK(rtab.getByID(id1).body == empty); 00347 BOOST_CHECK(rtab.getByID(id1).weight == ID_FAIL); 00348 BOOST_CHECK(rtab.getByID(id1).level == ID_FAIL); 00349 00350 ID id2 = rtab.storeAndGetID(rule2); 00351 ID id3 = rtab.storeAndGetID(rule3); 00352 ID id4 = rtab.storeAndGetID(rule4); 00353 BOOST_CHECK(rtab.getByID(id4).weight.address == 3); 00354 BOOST_CHECK(rtab.getByID(id4).level == idX); 00355 00356 LOG(INFO,"RuleTable" << rtab); 00357 } 00358 } 00359 00360 // Local Variables: 00361 // mode: C++ 00362 // End: