├── README.txt ├── prolog.cpp ├── tcalc.h └── test.cpp /README.txt: -------------------------------------------------------------------------------- 1 | C++ COMPILE-TIME PROLOG INTERPRETER 2 | ----------------------------------- 3 | 4 | C++ Templates are Turing Complete. It means that any computation expressible by 5 | a computer program can be computed, in some form, by a template metaprogram. 6 | 7 | prolog.cpp - Prolog-like program examples 8 | tcalc.h - Prolog interpreter source 9 | test.cpp - various tests 10 | 11 | P.S. Every good programmer should write at least one weird program, like chess 12 | game written in 'sed' utility, artificial neural network in Brainfuck, etc. 13 | -------------------------------------------------------------------------------- /prolog.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "tcalc.h" 3 | 4 | using namespace std; 5 | 6 | // symbolic & variable type declaration 7 | namespace tcalc 8 | { 9 | DECLARE_SYM( child ); 10 | DECLARE_SYM( boy ); 11 | DECLARE_SYM( girl ); 12 | DECLARE_SYM( bill ); 13 | DECLARE_SYM( frank ); 14 | DECLARE_SYM( alice ); 15 | DECLARE_SYM( alex ); 16 | DECLARE_VAR( X ); 17 | DECLARE_VAR( Y ); 18 | DECLARE_VAR( Z ); 19 | DECLARE_VAR( G ); 20 | 21 | DECLARE_SYM( trude ); 22 | DECLARE_SYM( sally ); 23 | DECLARE_SYM( erica ); 24 | DECLARE_SYM( tom ); 25 | DECLARE_SYM( mike ); 26 | DECLARE_SYM( father_child ); 27 | DECLARE_SYM( mother_child ); 28 | DECLARE_SYM( parent_child ); 29 | DECLARE_SYM( sibling ); 30 | } 31 | 32 | void TestProlog() 33 | { 34 | using namespace tcalc; 35 | using namespace tcalc::container::list; 36 | using namespace tcalc::prolog; 37 | 38 | typedef Term< Value_boy, List< Value_bill, NullItem > > TermA; 39 | typedef Term< Value_boy, List< Value_frank, NullItem > > TermB; 40 | typedef Term< Value_boy, List< Value_X, NullItem > > TermX; 41 | typedef Term< Value_boy, List< Value_G, NullItem > > TermG; 42 | 43 | typedef Term< Value_child, List< Value_X, NullItem > > TermChildX; // child(X). 44 | typedef Term< Value_boy, List< Value_X, NullItem > > TermBoyX; // boy(X). 45 | typedef Term< Value_girl, List< Value_X, NullItem > > TermGirlX; // girl(X). 46 | typedef Term< Value_boy, List< Value_alex, NullItem > > TermBoyAlex; // boy(alex). 47 | typedef Term< Value_girl, List< Value_alice, NullItem > > TermGirlAlice; // girl(alice). 48 | typedef Term< Value_child, List< Value_G, NullItem > > TermChildG; // child(G). 49 | 50 | typedef Rule< TermBoyAlex, NullItem > RuleBoyAlex; // boy(alex) :- True. 51 | typedef Rule< TermGirlAlice, NullItem > RuleGirlAlice; // girl(alice) :- True. 52 | typedef Rule< TermChildX, List< TermBoyX, NullItem > > RuleChildBoy; // child(X) :- boy(x). 53 | typedef Rule< TermChildX, List< TermGirlX, NullItem > > RuleChildGirl; // child(X) :- girl(x). 54 | 55 | typedef List< RuleChildBoy, List< RuleChildGirl, 56 | List< RuleBoyAlex, List< RuleGirlAlice, NullItem > > > > AllRules; 57 | 58 | typedef SearchGoal< TermChildG, AllRules > Result; 59 | //typedef SearchGoal< TermBoyX, AllRules > Result; 60 | cout << Result::ret << endl; 61 | PrintMap< Result::ResultEnv >::Print(); 62 | 63 | //////// 64 | 65 | // mother_child(trude, sally) 66 | typedef Term< Value_mother_child, List< Value_trude, List< Value_sally, NullItem > > > TermMotherChildTS; 67 | // father_child(tom, sally) 68 | typedef Term< Value_father_child, List< Value_tom, List< Value_sally, NullItem > > > TermFatherChildTS; 69 | // father_child(tom, erica) 70 | typedef Term< Value_father_child, List< Value_tom, List< Value_erica, NullItem > > > TermFatherChildTE; 71 | // father_child(mike, tom) 72 | typedef Term< Value_father_child, List< Value_mike, List< Value_tom, NullItem > > > TermFatherChildMT; 73 | 74 | // parent_child(Z, X) 75 | typedef Term< Value_parent_child, List< Value_Z, List< Value_X, NullItem > > > TermParentChildZX; 76 | // parent_child(Z, Y) 77 | typedef Term< Value_parent_child, List< Value_Z, List< Value_Y, NullItem > > > TermParentChildZY; 78 | // parent_child(X, Y) 79 | typedef Term< Value_parent_child, List< Value_X, List< Value_Y, NullItem > > > TermParentChildXY; 80 | // father_child(X, Y) 81 | typedef Term< Value_father_child, List< Value_X, List< Value_Y, NullItem > > > TermFatherChildXY; 82 | // mother_child(X, Y) 83 | typedef Term< Value_mother_child, List< Value_X, List< Value_Y, NullItem > > > TermMotherChildXY; 84 | // sibling(X, Y) 85 | typedef Term< Value_sibling, List< Value_X, List< Value_Y, NullItem > > > TermSiblingXY; 86 | 87 | // mother_child(trude, sally). 88 | typedef Rule< TermMotherChildTS, NullItem > RuleMotherChildTS; 89 | // father_child(tom, sally). 90 | typedef Rule< TermFatherChildTS, NullItem > RuleFatherChildTS; 91 | // father_child(tom, erica). 92 | typedef Rule< TermFatherChildTE, NullItem > RuleFatherChildTE; 93 | // father_child(mike, tom). 94 | typedef Rule< TermFatherChildMT, NullItem > RuleFatherChildMT; 95 | 96 | // sibling(X, Y) :- parent_child(Z, X), parent_child(Z, Y). 97 | typedef Rule< TermSiblingXY, List< TermParentChildZX, List< TermParentChildZY, NullItem > > > RuleSibling; 98 | 99 | // parent_child(X, Y) :- father_child(X, Y). 100 | typedef Rule< TermParentChildXY, List< TermFatherChildXY, NullItem > > RuleParentChild1; 101 | 102 | // parent_child(X, Y) :- mother_child(X, Y). 103 | typedef Rule< TermParentChildXY, List< TermMotherChildXY, NullItem > > RuleParentChild2; 104 | 105 | // sibling(sally, erica). 106 | typedef Term< Value_sibling, List< Value_sally, List< Value_erica, NullItem > > > TermQuestion; 107 | 108 | typedef List< RuleMotherChildTS, 109 | List< RuleFatherChildTS, 110 | List< RuleFatherChildTE, 111 | List< RuleFatherChildMT, 112 | List< RuleSibling, 113 | List< RuleParentChild1, 114 | List< RuleParentChild2, NullItem > > > > > > > AllRules2; 115 | 116 | typedef SearchGoal< TermQuestion, AllRules2 > Result2; 117 | cout << Result2::ret << endl; 118 | PrintMap< Result2::ResultEnv >::Print(); 119 | } 120 | 121 | int main() 122 | { 123 | TestProlog(); 124 | return 0; 125 | } 126 | -------------------------------------------------------------------------------- /tcalc.h: -------------------------------------------------------------------------------- 1 | /* 2 | C++ compile-time Prolog interpreter 3 | By Andrey Budnik, Belarus 4 | Public Domain 5 | */ 6 | 7 | #ifndef __TCALK_H 8 | #define __TCALK_H 9 | 10 | namespace tcalc { 11 | 12 | template< typename T, T v = T() > 13 | struct Value 14 | { 15 | enum { val = v }; 16 | typedef T value_type; 17 | }; 18 | 19 | 20 | #define DECLARE_NAME( s, isVar ) \ 21 | struct Value_##s { \ 22 | static const char *val; \ 23 | typedef char *value_type; \ 24 | static const bool var = isVar; \ 25 | }; \ 26 | const char *Value_##s::val = #s; \ 27 | 28 | #define DECLARE_SYM( s ) DECLARE_NAME( s, false ) 29 | #define DECLARE_VAR( s ) DECLARE_NAME( s, true ) 30 | 31 | template< typename T1, typename T2> 32 | struct TypeEqual 33 | { 34 | enum { val = 0 }; 35 | }; 36 | 37 | template< typename T > 38 | struct TypeEqual< T, T > 39 | { 40 | enum { val = 1 }; 41 | }; 42 | 43 | // comparision 44 | template< class V1, class V2> 45 | struct Less 46 | { 47 | enum { val = V1::val < V2::val }; 48 | }; 49 | 50 | template< class V1, class V2> 51 | struct LessOrEqual 52 | { 53 | enum { val = V1::val <= V2::val }; 54 | }; 55 | 56 | template< class V1, class V2 > 57 | struct Equal 58 | { 59 | enum { val = V1::val == V2::val }; 60 | }; 61 | 62 | template< class V1, class V2 > 63 | struct Greater 64 | { 65 | enum { val = V1::val > V2::val }; 66 | }; 67 | 68 | template< class V1, class V2 > 69 | struct GreaterOrEqual 70 | { 71 | enum { val = V1::val >= V2::val }; 72 | }; 73 | 74 | template< class V1, class V2 > 75 | class Min 76 | { 77 | template< class Vi1, class Vi2, int lesser > 78 | struct MinR; 79 | 80 | template< class Vi1, class Vi2 > 81 | struct MinR< Vi1, Vi2, 1 > 82 | { 83 | typedef Vi1 NextType; 84 | }; 85 | 86 | template< class Vi1, class Vi2 > 87 | struct MinR< Vi1, Vi2, 0 > 88 | { 89 | typedef Vi2 NextType; 90 | }; 91 | 92 | public: 93 | typedef typename MinR< V1, V2, Less< V1, V2 >::val >::NextType NextType; 94 | }; 95 | 96 | template< class V1, class V2 > 97 | class Max 98 | { 99 | template< class Vi1, class Vi2, int lesser > 100 | struct MaxR; 101 | 102 | template< class Vi1, class Vi2 > 103 | struct MaxR< Vi1, Vi2, 1 > 104 | { 105 | typedef Vi2 NextType; 106 | }; 107 | 108 | template< class Vi1, class Vi2 > 109 | struct MaxR< Vi1, Vi2, 0 > 110 | { 111 | typedef Vi1 NextType; 112 | }; 113 | 114 | public: 115 | typedef typename MaxR< V1, V2, Less< V1, V2 >::val >::NextType NextType; 116 | }; 117 | 118 | // arithmetic 119 | template< typename T, T v > 120 | struct Negate 121 | { 122 | enum { val = -v }; 123 | }; 124 | 125 | template< class V1, class V2 > 126 | struct Add 127 | { 128 | typedef Value< typename V1::value_type, V1::val + V2::val > NextType; 129 | }; 130 | 131 | template< class V1, class V2 > 132 | struct Sub 133 | { 134 | typedef Value< typename V1::value_type, V1::val - V2::val > NextType; 135 | }; 136 | 137 | template< class V1, class V2 > 138 | struct Mul 139 | { 140 | typedef Value< typename V1::value_type, V1::val * V2::val > NextType; 141 | }; 142 | 143 | template< class V1, class V2 > 144 | struct Div 145 | { 146 | typedef Value< typename V1::value_type, V1::val / V2::val > NextType; 147 | }; 148 | 149 | template< class V, unsigned p > 150 | struct Power 151 | { 152 | typedef Value< typename V::value_type, Power< V, p - 1 >::NextType::val * V::val > NextType; 153 | }; 154 | 155 | template< class V > 156 | struct Power< V, 1 > 157 | { 158 | typedef V NextType; 159 | }; 160 | 161 | template< class V > 162 | struct Power< V, 0 > 163 | { 164 | typedef Value< typename V::value_type, 1 > NextType; 165 | }; 166 | 167 | // special-purpose 168 | template< unsigned v > 169 | struct Factorial 170 | { 171 | enum { val = Factorial< v - 1 >::val * v }; 172 | }; 173 | 174 | template<> 175 | struct Factorial<0> 176 | { 177 | enum { val = 1 }; 178 | }; 179 | 180 | //////////////////////////////// 181 | namespace container { 182 | 183 | namespace list { 184 | 185 | struct NullItem 186 | { 187 | static void Print() { std::cout << std::endl; } 188 | }; 189 | 190 | template< typename V, typename L > 191 | struct List 192 | { 193 | typedef V value_type; 194 | 195 | static void Print() 196 | { 197 | std::cout << value_type::val << ", "; 198 | L::Print(); 199 | } 200 | }; 201 | 202 | template< class List > struct ListLength; 203 | 204 | template<> 205 | struct ListLength< NullItem > 206 | { 207 | static const unsigned val = 0; 208 | }; 209 | 210 | template< class V, class L > 211 | struct ListLength< List< V, L > > 212 | { 213 | static const unsigned val = 1 + ListLength::val; 214 | }; 215 | 216 | template< class List > struct Next; 217 | 218 | template< class V, class L > 219 | struct Next< List< V, L > > 220 | { 221 | typedef L NextType; 222 | }; 223 | 224 | template< class L, int step > 225 | class Advance 226 | { 227 | typedef typename Next< L >::NextType Forward; 228 | public: 229 | typedef typename Advance< Forward, step - 1 >::NextType NextType; 230 | }; 231 | 232 | template< class L > 233 | class Advance< L, 1 > 234 | { 235 | public: 236 | typedef typename Next< L >::NextType NextType; 237 | }; 238 | 239 | template< class L > 240 | class Advance< L, 0 > 241 | { 242 | public: 243 | typedef L NextType; 244 | }; 245 | 246 | template< class L, int length = ListLength< L >::val > 247 | class Reverse 248 | { 249 | typedef typename Advance< L, length - 1 >::NextType::value_type Last; 250 | public: 251 | typedef List< Last, typename Reverse< L, length - 1 >::NextType > NextType; 252 | }; 253 | 254 | template< class L > 255 | class Reverse< L, 1 > 256 | { 257 | typedef typename L::value_type First; 258 | public: 259 | typedef List< First, NullItem > NextType; 260 | }; 261 | 262 | template< class L > 263 | class PopBack 264 | { 265 | template< class Li, int length > 266 | class PopBackR 267 | { 268 | typedef typename Next< Li >::NextType Remaining; 269 | public: 270 | typedef List< typename Li::value_type, typename PopBackR< Remaining, length - 1 >::NextType > NextType; 271 | }; 272 | 273 | template< class Li > 274 | class PopBackR< Li, 2 > 275 | { 276 | public: 277 | typedef List< typename Li::value_type, NullItem > NextType; 278 | }; 279 | 280 | template< class Li > 281 | class PopBackR< Li, 1 > 282 | { 283 | public: 284 | typedef NullItem NextType; 285 | }; 286 | 287 | public: 288 | typedef typename PopBackR< L, ListLength< L >::val >::NextType NextType; 289 | }; 290 | 291 | template< class L > 292 | struct PopFront 293 | { 294 | typedef typename Next< L >::NextType NextType; 295 | }; 296 | 297 | template< class V, class L > 298 | class PushBack 299 | { 300 | typedef typename Reverse< L >::NextType Reversed; 301 | typedef List< V, Reversed > ReversedA; 302 | public: 303 | typedef typename Reverse< ReversedA >::NextType NextType; 304 | }; 305 | 306 | template< class V > 307 | class PushBack< V, NullItem > 308 | { 309 | public: 310 | typedef List< V, NullItem > NextType; 311 | }; 312 | 313 | template< unsigned n, int i = 0, int until = n + i, class G = NullItem > 314 | class Generate 315 | { 316 | typedef List< Value< int, i >, G > NewList; 317 | public: 318 | typedef typename Generate< n, i + 1, until, NewList >::NextType NextType; 319 | }; 320 | 321 | template< unsigned n, int until, class G > 322 | class Generate 323 | { 324 | public: 325 | typedef G NextType; 326 | }; 327 | 328 | template< class L1, class L2 > 329 | class Merge 330 | { 331 | typedef typename PushBack< typename L2::value_type, L1 >::NextType MergedWithFirst; 332 | typedef typename Next< L2 >::NextType L2_NextType; 333 | public: 334 | typedef typename Merge< MergedWithFirst, L2_NextType >::NextType NextType; 335 | }; 336 | 337 | template< class L1 > 338 | class Merge< L1, NullItem > 339 | { 340 | public: 341 | typedef L1 NextType; 342 | }; 343 | 344 | template< class L, unsigned n, unsigned i = 0 > 345 | class First 346 | { 347 | template< class Li, unsigned ni, class Ri, unsigned ii > 348 | class FirstR 349 | { 350 | typedef typename PushBack< typename Li::value_type, Ri >::NextType Ls; 351 | typedef typename Next< Li >::NextType Forward; 352 | public: 353 | typedef typename FirstR< Forward, ni, Ls, ii + 1 >::NextType NextType; 354 | }; 355 | 356 | template< class Li, unsigned ni, class Ri > 357 | class FirstR< Li, ni, Ri, ni > 358 | { 359 | public: 360 | typedef Ri NextType; 361 | }; 362 | 363 | typedef List< typename L::value_type, NullItem > Trivial; 364 | typedef typename Next< L >::NextType Forward; 365 | public: 366 | typedef typename FirstR< Forward, n, Trivial, 1 >::NextType NextType; 367 | }; 368 | 369 | template< class L, class Item, unsigned index, unsigned length = ListLength< L >::val > 370 | class InsertAt 371 | { 372 | typedef typename First< L, index >::NextType L1; 373 | typedef typename Advance< L, index >::NextType L2; 374 | typedef typename PushBack< Item, L1 >::NextType L1PlusItem; 375 | public: 376 | typedef typename Merge< L1PlusItem, L2 >::NextType NextType; 377 | }; 378 | 379 | template< class L, class Item, unsigned index > 380 | class InsertAt< L, Item, index, index > 381 | { 382 | public: 383 | typedef typename PushBack< Item, L >::NextType NextType; 384 | }; 385 | 386 | template< class L, class Item, unsigned length > 387 | class InsertAt< L, Item, 0, length > 388 | { 389 | public: 390 | typedef List< Item, L > NextType; 391 | }; 392 | 393 | template< class L, unsigned index > 394 | class EraseAtIndex 395 | { 396 | typedef typename First::NextType L1; 397 | typedef typename Advance::NextType L2; 398 | public: 399 | typedef typename Merge< L1, L2 >::NextType NextType; 400 | }; 401 | 402 | template< class L > 403 | class EraseAtIndex< L, 0 > 404 | { 405 | public: 406 | typedef typename Next::NextType NextType; 407 | }; 408 | 409 | template< class Ls, class it > 410 | class Search 411 | { 412 | public: 413 | static const int NOT_FOUND = -1; 414 | 415 | private: 416 | template< class L, class item, unsigned i, int eq > 417 | class SearchR; 418 | 419 | template< class L, class item, unsigned i > 420 | class SearchR< L, item, i, 1 > 421 | { 422 | public: 423 | enum { val = i }; 424 | }; 425 | 426 | template< class item, unsigned i > 427 | class SearchR< NullItem, item, i, 1 > 428 | { 429 | public: 430 | enum { val = i }; 431 | }; 432 | 433 | template< class item, unsigned i > 434 | class SearchR< NullItem, item, i, 0 > 435 | { 436 | public: 437 | enum { val = NOT_FOUND }; 438 | }; 439 | 440 | template< class L, class item, unsigned i > 441 | class SearchR< L, item, i, 0 > 442 | { 443 | typedef typename Next::NextType NextType; 444 | public: 445 | enum { val = SearchR< NextType, item, i + 1, Equal< typename NextType::value_type, item >::val >::val }; 446 | }; 447 | 448 | public: 449 | enum { val = SearchR< Ls, it, 0, Equal< typename Ls::value_type, it >::val >::val }; 450 | }; 451 | 452 | template< class L, typename Min = typename L::value_type > 453 | class FindMinimum 454 | { 455 | typedef typename Next::NextType Forward; 456 | typedef typename tcalc::Min< typename L::value_type, Min >::NextType CurrentMin; 457 | public: 458 | typedef typename FindMinimum< Forward, CurrentMin >::NextType NextType; 459 | }; 460 | 461 | template< class Min > 462 | class FindMinimum< NullItem, Min > 463 | { 464 | public: 465 | typedef Min NextType; 466 | }; 467 | 468 | template< class Ls, class it > 469 | class LowerBound 470 | { 471 | template< class L, class item, unsigned i, int eq > 472 | class LowerR; 473 | 474 | template< class L, class item, unsigned i > 475 | class LowerR< L, item, i, 1 > 476 | { 477 | public: 478 | enum { val = i - 1 }; 479 | }; 480 | 481 | template< class L, class item > 482 | class LowerR< L, item, 0, 1 > 483 | { 484 | public: 485 | enum { val = 0 }; 486 | }; 487 | 488 | template< class item, unsigned i > 489 | class LowerR< NullItem, item, i, 1 > 490 | { 491 | public: 492 | enum { val = i - 1 }; 493 | }; 494 | 495 | template< class item, unsigned i > 496 | class LowerR< NullItem, item, i, 0 > 497 | { 498 | public: 499 | enum { val = i }; 500 | }; 501 | 502 | template< class L, class item, unsigned i > 503 | class LowerR< L, item, i, 0 > 504 | { 505 | typedef typename Next::NextType NextType; 506 | public: 507 | enum { val = LowerR< NextType, item, i + 1, Greater< typename L::value_type, item >::val >::val }; 508 | }; 509 | 510 | public: 511 | enum { val = LowerR< Ls, it, 0, Greater< typename Ls::value_type, it >::val >::val }; 512 | }; 513 | 514 | 515 | template< class L1, class L2 > 516 | class MergeSorted 517 | { 518 | typedef typename Next< L2 >::NextType L2MinusMin; 519 | 520 | typedef typename L2::value_type Min; 521 | typedef LowerBound< L1, Min > LB; 522 | typedef typename InsertAt< L1, Min, LB::val >::NextType L1PlusMin; 523 | public: 524 | typedef typename MergeSorted< L1PlusMin, L2MinusMin >::NextType NextType; 525 | }; 526 | 527 | template< class L1 > 528 | class MergeSorted< L1, NullItem > 529 | { 530 | public: 531 | typedef L1 NextType; 532 | }; 533 | 534 | template< class L, unsigned length = ListLength< L >::val > 535 | class MergeSort 536 | { 537 | typedef ListLength< L > Length; 538 | typedef typename First< L, Length::val / 2 >::NextType L1; 539 | typedef typename Advance< L, Length::val / 2 >::NextType L2; 540 | 541 | typedef typename MergeSort< L1 >::NextType L1_sorted; 542 | typedef typename MergeSort< L2 >::NextType L2_sorted; 543 | public: 544 | typedef typename MergeSorted< L1_sorted, L2_sorted >::NextType NextType; 545 | }; 546 | 547 | template< class L > 548 | class MergeSort< L, 2 > 549 | { 550 | typedef typename L::value_type E1; 551 | typedef typename Next::NextType Forward; 552 | typedef typename Forward::value_type E2; 553 | 554 | typedef typename Min::NextType R1; 555 | typedef typename Max::NextType R2; 556 | public: 557 | typedef List< R1, List< R2, NullItem > > NextType; 558 | }; 559 | 560 | template< class L > 561 | class MergeSort< L, 1 > 562 | { 563 | public: 564 | typedef L NextType; 565 | }; 566 | 567 | // functional 568 | template< class L, template class F, class BindParam > 569 | class Map 570 | { 571 | template< template class T, class Param, class Value > 572 | struct Mutator : T< Param, Value > 573 | { 574 | }; 575 | 576 | typedef typename L::value_type E; 577 | typedef typename Mutator< F, BindParam, E >::NextType Mut; 578 | 579 | typedef typename Next::NextType Forward; 580 | public: 581 | typedef List< Mut, typename Map< Forward, F, BindParam >::NextType > NextType; 582 | }; 583 | 584 | template< template class F, class BindParam > 585 | class Map< NullItem, F, BindParam > 586 | { 587 | public: 588 | typedef NullItem NextType; 589 | }; 590 | 591 | template< class L, template class F, class Value > 592 | class Fold 593 | { 594 | template< template class T, class Param, class V > 595 | struct Mutator : T< Param, V > 596 | { 597 | }; 598 | 599 | typedef typename L::value_type E; 600 | typedef typename Mutator< F, Value, E >::NextType Mut; 601 | 602 | typedef typename Next::NextType Forward; 603 | public: 604 | typedef typename Fold< Forward, F, Mut >::NextType NextType; 605 | }; 606 | 607 | template< template class F, class Value > 608 | class Fold< NullItem, F, Value > 609 | { 610 | public: 611 | typedef Value NextType; 612 | }; 613 | 614 | template< class L, template class LeftPredicate, class BindParam, class G = NullItem > 615 | class Filter 616 | { 617 | template< class Param, template class P, class Value > 618 | struct Predicate : P< Value, Param > 619 | { 620 | }; 621 | 622 | template< class Li, class V, int eq > 623 | struct Match 624 | { 625 | typedef typename PushBack< V, Li >::NextType NextType; 626 | }; 627 | 628 | template< class Li, class V > 629 | struct Match< Li, V, 0 > 630 | { 631 | typedef Li NextType; 632 | }; 633 | 634 | typedef typename L::value_type E; 635 | typedef Predicate< BindParam, LeftPredicate, E > AppliedPredicate; 636 | typedef typename Match< G, E, AppliedPredicate::val >::NextType Matched; 637 | 638 | typedef typename Next::NextType Forward; 639 | public: 640 | typedef typename Filter< Forward, LeftPredicate, BindParam, Matched >::NextType NextType; 641 | }; 642 | 643 | template< template class LeftPredicate, class BindParam, class G > 644 | class Filter< NullItem, LeftPredicate, BindParam, G > 645 | { 646 | public: 647 | typedef G NextType; 648 | }; 649 | 650 | } // namespace list 651 | 652 | namespace map { 653 | 654 | using namespace list; // map implemented as list of Key-Value pairs 655 | 656 | template< typename K, typename V > 657 | struct Pair 658 | { 659 | typedef K Key; 660 | typedef V Value; 661 | }; 662 | 663 | template< typename Pair > 664 | struct GetPairValue 665 | { 666 | typedef typename Pair::Value Value; 667 | }; 668 | 669 | template<> 670 | struct GetPairValue< NullItem > 671 | { 672 | typedef NullItem Value; 673 | }; 674 | 675 | template< typename Key, typename Map > 676 | class FindKey 677 | { 678 | template< typename K, typename M, int eq > 679 | struct FindKeyR 680 | { 681 | typedef typename M::value_type NextType; 682 | }; 683 | 684 | template< typename K, typename M > 685 | struct FindKeyR< K, M, 0 > 686 | { 687 | typedef typename FindKey< K, typename Next< M >::NextType >::NextType NextType; 688 | }; 689 | 690 | typedef typename Map::value_type Item; 691 | typedef typename Item::Key K; 692 | public: 693 | typedef typename FindKeyR< Key, Map, TypeEqual< Key, K >::val >::NextType NextType; 694 | }; 695 | 696 | template< typename Key > 697 | class FindKey< Key, NullItem > 698 | { 699 | public: 700 | typedef NullItem NextType; 701 | }; 702 | 703 | template< class Pair, typename Map, unsigned index = 0, typename Forward = Map > 704 | class AddKey 705 | { 706 | template< typename P, typename M, unsigned i, typename F, int eq > // eq => replace 707 | class AddKeyR 708 | { 709 | typedef typename InsertAt< M, P, i >::NextType Left; 710 | typedef typename First< Left, i + 1 >::NextType L1; 711 | typedef typename Advance< M, i + 1 >::NextType Right; 712 | public: 713 | typedef typename Merge< L1, Right >::NextType NextType; 714 | }; 715 | 716 | template< typename P, typename M, unsigned i, typename F > 717 | class AddKeyR< P, M, i, F, 0 > 718 | { 719 | public: 720 | typedef typename AddKey< P, M, i + 1, typename Next< F >::NextType >::NextType NextType; 721 | }; 722 | 723 | template< typename P, unsigned i, typename F, int eq > // empty map 724 | class AddKeyR< P, NullItem, i, F, eq > 725 | { 726 | public: 727 | typedef List< P, NullItem > NextType; 728 | }; 729 | 730 | typedef typename Forward::value_type Item; 731 | typedef typename Item::Key K; 732 | typedef typename Pair::Key Key; 733 | public: 734 | typedef typename AddKeyR< Pair, Map, index, Forward, TypeEqual< K, Key >::val >::NextType NextType; 735 | }; 736 | 737 | template< class Pair, typename Map, unsigned index > 738 | class AddKey< Pair, Map, index, NullItem > 739 | { 740 | public: 741 | typedef List< Pair, Map > NextType; 742 | }; 743 | 744 | template< class Key, typename Map, unsigned index = 0, typename Forward = Map > 745 | class EraseKey 746 | { 747 | template< typename K, typename M, unsigned i, typename F, int eq > 748 | class EraseKeyR 749 | { 750 | public: 751 | typedef typename EraseAtIndex< M, i >::NextType NextType; 752 | }; 753 | 754 | template< typename K, typename M, unsigned i, typename F > 755 | class EraseKeyR< K, M, i, F, 0 > 756 | { 757 | public: 758 | typedef typename EraseKey< K, M, i + 1, typename Next< F >::NextType >::NextType NextType; 759 | }; 760 | 761 | template< typename K, unsigned i, typename F, int eq > // empty map 762 | class EraseKeyR< K, NullItem, i, F, eq > 763 | { 764 | public: 765 | typedef NullItem NextType; 766 | }; 767 | 768 | typedef typename Forward::value_type Item; 769 | typedef typename Item::Key K; 770 | public: 771 | typedef typename EraseKeyR< Key, Map, index, Forward, TypeEqual< K, Key >::val >::NextType NextType; 772 | }; 773 | 774 | template< class Key, typename Map, unsigned index > 775 | class EraseKey< Key, Map, index, NullItem > 776 | { 777 | public: 778 | typedef Map NextType; 779 | }; 780 | 781 | template< typename Map1, typename Map2 > 782 | class MergeMap 783 | { 784 | typedef typename Map2::value_type Pair2; 785 | typedef typename Next::NextType Forward; 786 | 787 | typedef typename AddKey< Pair2, Map1 >::NextType MergedWithFirst; 788 | public: 789 | typedef typename MergeMap< MergedWithFirst, Forward >::NextType NextType; 790 | }; 791 | 792 | template< typename Map1 > 793 | class MergeMap< Map1, NullItem > 794 | { 795 | public: 796 | typedef Map1 NextType; 797 | }; 798 | 799 | template< typename Map2 > 800 | class MergeMap< NullItem, Map2 > 801 | { 802 | public: 803 | typedef Map2 NextType; 804 | }; 805 | 806 | template<> 807 | class MergeMap< NullItem, NullItem > 808 | { 809 | public: 810 | typedef NullItem NextType; 811 | }; 812 | 813 | template< typename Map > 814 | class PrintMap 815 | { 816 | typedef typename Map::value_type PairType; 817 | typedef typename PairType::Key K; 818 | typedef typename PairType::Value V; 819 | 820 | typedef typename Next< Map >::NextType Forward; 821 | public: 822 | static void Print() 823 | { 824 | std::cout << "(" << K::val << ", " << V::val << "),"; 825 | PrintMap< Forward >::Print(); 826 | } 827 | }; 828 | 829 | template<> 830 | class PrintMap< NullItem > 831 | { 832 | public: 833 | static void Print() 834 | { 835 | std::cout << std::endl; 836 | } 837 | }; 838 | 839 | } // namespace map 840 | 841 | } // namespace container 842 | 843 | namespace prolog { 844 | 845 | using namespace container::list; 846 | using namespace container::map; 847 | 848 | template< typename Predicate, typename ArgList > 849 | struct Term 850 | { 851 | typedef Predicate Pred; 852 | typedef ArgList Args; 853 | }; 854 | 855 | template< typename Term, typename TermList > 856 | struct Rule 857 | { 858 | typedef Term Head; 859 | typedef TermList Goals; 860 | }; 861 | 862 | template< typename Rule, typename Parent = NullItem, typename Env = NullItem, unsigned i = 0 > 863 | struct Goal 864 | { 865 | typedef Rule R; 866 | typedef Parent P; 867 | typedef Env E; 868 | static const unsigned index = i; 869 | }; 870 | 871 | 872 | template< typename SrcTerm, typename SrcEnv, typename DestTerm, typename DestEnv > 873 | class Unify 874 | { 875 | template< typename ST, typename SE, typename DT, typename DE, unsigned nArgs, int i > 876 | class UnifyR 877 | { 878 | typedef typename Advance< typename ST::Args, i >::NextType STT; 879 | typedef typename STT::value_type SrcArg; 880 | enum { sVar = SrcArg::var }; 881 | 882 | typedef typename Advance< typename DT::Args, i >::NextType DTT; 883 | typedef typename DTT::value_type DestArg; 884 | enum { dVar = DestArg::var }; 885 | 886 | template< typename sArg, typename sEnv, int isVar > 887 | struct DefineSrcVal 888 | { 889 | typedef typename FindKey< sArg, sEnv >::NextType FoundPair; 890 | typedef typename GetPairValue< FoundPair >::Value Val; 891 | }; 892 | 893 | template< typename sArg, typename sEnv > 894 | struct DefineSrcVal< sArg, sEnv, 0 > 895 | { 896 | typedef sArg Val; 897 | }; 898 | 899 | typedef typename DefineSrcVal< SrcArg, SE, sVar >::Val SrcVal; 900 | 901 | 902 | template< typename STi, typename SEi, typename DTi, typename DEi, unsigned nArgsi, int ii, int eq > 903 | class CompareWithSrcVal 904 | { 905 | typedef UnifyR< STi, SEi, DTi, DEi, nArgsi, ii + 1 > Result; // next iteration 906 | public: 907 | typedef typename Result::ResultEnv ResultEnv; 908 | enum { ret = Result::ret }; 909 | }; 910 | 911 | template< typename STi, typename SEi, typename DTi, typename DEi, unsigned nArgsi, int ii > 912 | class CompareWithSrcVal< STi, SEi, DTi, DEi, nArgsi, ii, 0 > 913 | { 914 | public: 915 | typedef DEi ResultEnv; 916 | enum { ret = 0 }; 917 | }; 918 | 919 | template< typename STi, typename SEi, typename DTi, typename DEi, unsigned nArgsi, int ii, typename DestVal, int eq > 920 | class CheckDestVal 921 | { 922 | typedef typename AddKey< Pair< DestArg, SrcVal >, DEi >::NextType Updated; 923 | typedef UnifyR< STi, SEi, DTi, Updated, nArgsi, ii + 1 > Result; // next iteration 924 | public: 925 | typedef typename Result::ResultEnv ResultEnv; 926 | enum { ret = Result::ret }; 927 | }; 928 | 929 | template< typename STi, typename SEi, typename DTi, typename DEi, unsigned nArgsi, int ii, typename DestVal > 930 | class CheckDestVal< STi, SEi, DTi, DEi, nArgsi, ii, DestVal, 0 > 931 | { 932 | typedef CompareWithSrcVal< STi, SEi, DTi, DEi, nArgsi, ii, TypeEqual< DestVal, SrcVal >::val > Result; 933 | public: 934 | typedef typename Result::ResultEnv ResultEnv; 935 | enum { ret = Result::ret }; 936 | }; 937 | 938 | template< typename STi, typename SEi, typename DTi, typename DEi, unsigned nArgsi, int ii, int eq > 939 | class CheckDestArg 940 | { 941 | typedef typename FindKey< DestArg, DE >::NextType DestVal; 942 | typedef CheckDestVal< STi, SEi, DTi, DEi, nArgsi, ii, DestVal, TypeEqual< DestVal, NullItem >::val > Result; 943 | public: 944 | typedef typename Result::ResultEnv ResultEnv; 945 | enum { ret = Result::ret }; 946 | }; 947 | 948 | template< typename STi, typename SEi, typename DTi, typename DEi, unsigned nArgsi, int ii > 949 | class CheckDestArg< STi, SEi, DTi, DEi, nArgsi, ii, 0 > 950 | { 951 | typedef CompareWithSrcVal< STi, SEi, DTi, DEi, nArgsi, ii, TypeEqual< DestArg, SrcVal >::val > Result; 952 | public: 953 | typedef typename Result::ResultEnv ResultEnv; 954 | enum { ret = Result::ret }; 955 | }; 956 | 957 | template< typename STi, typename SEi, typename DTi, typename DEi, unsigned nArgsi, int ii, int eq > 958 | class CheckSrcVal 959 | { 960 | typedef UnifyR< STi, SEi, DTi, DEi, nArgsi, ii + 1 > Result; // next iteration 961 | public: 962 | typedef typename Result::ResultEnv ResultEnv; 963 | enum { ret = Result::ret }; 964 | }; 965 | 966 | template< typename STi, typename SEi, typename DTi, typename DEi, unsigned nArgsi, int ii > 967 | class CheckSrcVal< STi, SEi, DTi, DEi, nArgsi, ii, 0 > 968 | { 969 | typedef CheckDestArg< STi, SEi, DTi, DEi, nArgsi, ii, dVar > Result; 970 | public: 971 | typedef typename Result::ResultEnv ResultEnv; 972 | enum { ret = Result::ret }; 973 | }; 974 | 975 | typedef CheckSrcVal< ST, SE, DT, DE, nArgs, i, TypeEqual< SrcVal, NullItem >::val > Result; 976 | public: 977 | typedef typename Result::ResultEnv ResultEnv; 978 | enum { ret = Result::ret }; 979 | }; 980 | 981 | template< typename ST, typename SE, typename DT, typename DE, unsigned nArgs > 982 | class UnifyR< ST, SE, DT, DE, nArgs, nArgs > 983 | { 984 | public: 985 | typedef DE ResultEnv; 986 | enum { ret = 1 }; 987 | }; 988 | 989 | template< typename ST, typename SE, typename DT, typename DE, unsigned nArgs, int eq > 990 | class CmpPred 991 | { 992 | typedef UnifyR< ST, SE, DT, DE, nArgs, 0 > Result; 993 | public: 994 | typedef typename Result::ResultEnv ResultEnv; 995 | enum { ret = Result::ret }; 996 | }; 997 | 998 | template< typename ST, typename SE, typename DT, typename DE, unsigned nArgs > 999 | class CmpPred< ST, SE, DT, DE, nArgs, 0 > 1000 | { 1001 | public: 1002 | typedef DE ResultEnv; 1003 | enum { ret = 0 }; 1004 | }; 1005 | 1006 | template< typename ST, typename SE, typename DT, typename DE, unsigned nSrcArgs, int eq > 1007 | class CmpArgs 1008 | { 1009 | typedef TypeEqual< typename ST::Pred, typename DT::Pred > ComparePredicates; 1010 | typedef CmpPred< ST, SE, DT, DE, nSrcArgs, ComparePredicates::val > Result; 1011 | public: 1012 | typedef typename Result::ResultEnv ResultEnv; 1013 | enum { ret = Result::ret }; 1014 | }; 1015 | 1016 | template< typename ST, typename SE, typename DT, typename DE, unsigned nSrcArgs > 1017 | class CmpArgs< ST, SE, DT, DE, nSrcArgs, 0 > 1018 | { 1019 | public: 1020 | typedef DE ResultEnv; 1021 | enum { ret = 0 }; 1022 | }; 1023 | 1024 | typedef typename SrcTerm::Args SrcArgs; 1025 | typedef typename DestTerm::Args DestArgs; 1026 | typedef CmpArgs< SrcTerm, SrcEnv, DestTerm, DestEnv, ListLength::val, 1027 | ListLength::val == ListLength::val > Result; 1028 | public: 1029 | typedef typename Result::ResultEnv ResultEnv; 1030 | enum { ret = Result::ret }; 1031 | }; 1032 | 1033 | 1034 | DECLARE_SYM( got_ ); 1035 | DECLARE_SYM( goal_ ); 1036 | 1037 | template< typename SearchTerm, typename GlobalRules > 1038 | class SearchGoal 1039 | { 1040 | typedef Term< Value_got_, List< Value_goal_, NullItem > > GoalTerm; 1041 | typedef Rule< GoalTerm, List< SearchTerm, NullItem > > MainRule; 1042 | typedef Goal< MainRule > MainGoal; 1043 | 1044 | template< typename GoalStack, typename Rules > 1045 | class SearchR 1046 | { 1047 | template< typename GS, typename G, int eq > 1048 | class CheckOriginalGoal 1049 | { 1050 | typedef SearchR< GS, Rules > Result; 1051 | public: 1052 | typedef typename Merge< typename G::E, typename Result::ResultEnv >::NextType ResultEnv; 1053 | enum { ret = 1 }; 1054 | }; 1055 | 1056 | template< typename GS, typename G > 1057 | class CheckOriginalGoal< GS, G, 0 > 1058 | { 1059 | typedef typename G::P P; 1060 | typedef typename G::R Rule; 1061 | 1062 | typedef typename P::R PRule; 1063 | typedef typename PRule::Goals PRuleGoals; 1064 | typedef typename Advance< PRuleGoals, P::index >::NextType PRuleGoalsOffset; 1065 | typedef typename PRuleGoalsOffset::value_type PGoal; 1066 | 1067 | typedef Unify< typename Rule::Head, typename G::E, PGoal, typename P::E > Unified; 1068 | 1069 | typedef Goal< PRule, typename P::P, typename Unified::ResultEnv, P::index + 1 > NewParent; 1070 | 1071 | typedef List< NewParent, GS > PushNewParent; 1072 | 1073 | typedef SearchR< PushNewParent, Rules > Result; 1074 | public: 1075 | typedef typename Result::ResultEnv ResultEnv; 1076 | enum { ret = Result::ret }; 1077 | }; 1078 | 1079 | template< typename GS, bool ge > 1080 | class CheckGoalIndex 1081 | { 1082 | typedef typename GS::value_type G; 1083 | typedef typename G::P P; 1084 | typedef typename Next< GS >::NextType PopG; 1085 | 1086 | typedef CheckOriginalGoal< PopG, G, TypeEqual< P, NullItem >::val > Result; 1087 | public: 1088 | typedef typename Result::ResultEnv ResultEnv; 1089 | enum { ret = Result::ret }; 1090 | }; 1091 | 1092 | template< typename G, typename GS, typename T, typename CurrentR > 1093 | class IterateRules 1094 | { 1095 | template< typename GSi, typename Child, int eq > 1096 | class CheckAnswer 1097 | { 1098 | typedef List< Child, GSi > PushChild; 1099 | typedef IterateRules< G, PushChild, T, typename Next::NextType > Result; 1100 | public: 1101 | typedef typename Result::ResultEnv ResultEnv; 1102 | enum { ret = Result::ret }; 1103 | }; 1104 | 1105 | template< typename GSi, typename Child > 1106 | class CheckAnswer< GSi, Child, 0 > 1107 | { 1108 | typedef IterateRules< G, GSi, T, typename Next::NextType > Result; 1109 | public: 1110 | typedef typename Result::ResultEnv ResultEnv; 1111 | enum { ret = Result::ret }; 1112 | }; 1113 | 1114 | template< typename GSi, int eq > 1115 | class CheckArgs 1116 | { 1117 | typedef typename CurrentR::value_type CurrentRule; 1118 | 1119 | typedef Unify< T, typename G::E, typename CurrentRule::Head, NullItem > Unified; 1120 | typedef Goal< CurrentRule, G, typename Unified::ResultEnv > Child; 1121 | 1122 | typedef CheckAnswer< GSi, Child, Unified::ret > Result; 1123 | public: 1124 | typedef typename Result::ResultEnv ResultEnv; 1125 | enum { ret = Result::ret }; 1126 | }; 1127 | 1128 | template< typename GSi > 1129 | class CheckArgs< GSi, 0 > 1130 | { 1131 | typedef IterateRules< G, GSi, T, typename Next::NextType > Result; 1132 | public: 1133 | typedef typename Result::ResultEnv ResultEnv; 1134 | enum { ret = Result::ret }; 1135 | }; 1136 | 1137 | template< typename GSi, int eq > 1138 | class CheckPredicates 1139 | { 1140 | typedef typename CurrentR::value_type CurrentRule; 1141 | typedef typename CurrentRule::Head CurrentRuleHead; 1142 | 1143 | typedef CheckArgs< GSi, ListLength< typename T::Args >::val == ListLength< typename CurrentRuleHead::Args >::val > Result; 1144 | public: 1145 | typedef typename Result::ResultEnv ResultEnv; 1146 | enum { ret = Result::ret }; 1147 | }; 1148 | 1149 | template< typename GSi > 1150 | class CheckPredicates< GSi, 0 > 1151 | { 1152 | typedef IterateRules< G, GSi, T, typename Next::NextType > Result; 1153 | public: 1154 | typedef typename Result::ResultEnv ResultEnv; 1155 | enum { ret = Result::ret }; 1156 | }; 1157 | 1158 | typedef typename CurrentR::value_type CurrentRule; 1159 | typedef typename CurrentRule::Head CurrentRuleHead; 1160 | 1161 | typedef CheckPredicates< GS, TypeEqual< typename CurrentRuleHead::Pred, typename T::Pred >::val > Result; 1162 | public: 1163 | typedef typename Result::ResultEnv ResultEnv; 1164 | enum { ret = Result::ret }; 1165 | }; 1166 | 1167 | template< typename G, typename GS, typename T > 1168 | class IterateRules< G, GS, T, NullItem > 1169 | { 1170 | typedef SearchR< GS, Rules > Result; 1171 | public: 1172 | typedef typename Result::ResultEnv ResultEnv; 1173 | enum { ret = Result::ret }; 1174 | }; 1175 | 1176 | template< typename GS > 1177 | class CheckGoalIndex< GS, false > 1178 | { 1179 | typedef typename GS::value_type G; 1180 | typedef typename Next< GS >::NextType PopG; 1181 | 1182 | typedef typename G::R Rule; 1183 | typedef typename Rule::Goals RGoals; 1184 | typedef typename Advance< RGoals, G::index >::NextType RGoalsOffset; 1185 | typedef typename RGoalsOffset::value_type T; 1186 | 1187 | typedef IterateRules< G, PopG, T, Rules > Result; 1188 | public: 1189 | typedef typename Result::ResultEnv ResultEnv; 1190 | enum { ret = Result::ret }; 1191 | }; 1192 | 1193 | typedef typename GoalStack::value_type G; 1194 | typedef typename G::R R; 1195 | typedef typename R::Goals SubGoals; 1196 | 1197 | typedef CheckGoalIndex< GoalStack, ( G::index >= ListLength::val ) > Result; 1198 | public: 1199 | typedef typename Result::ResultEnv ResultEnv; 1200 | enum { ret = Result::ret }; 1201 | }; 1202 | 1203 | template< typename Rules > 1204 | class SearchR< NullItem, Rules > 1205 | { 1206 | public: 1207 | typedef NullItem ResultEnv; 1208 | enum { ret = 0 }; 1209 | }; 1210 | 1211 | typedef SearchR< List< MainGoal, NullItem >, GlobalRules > Result; 1212 | public: 1213 | typedef typename Result::ResultEnv ResultEnv; 1214 | enum { ret = Result::ret }; 1215 | }; 1216 | 1217 | } // namespace prolog 1218 | 1219 | } // namespace tcalc 1220 | 1221 | #endif 1222 | -------------------------------------------------------------------------------- /test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "tcalc.h" 3 | 4 | using namespace std; 5 | 6 | // symbolic & variable type declaration 7 | namespace tcalc 8 | { 9 | DECLARE_SYM( child ); 10 | DECLARE_SYM( boy ); 11 | DECLARE_SYM( girl ); 12 | DECLARE_SYM( bill ); 13 | DECLARE_SYM( frank ); 14 | DECLARE_SYM( alice ); 15 | DECLARE_SYM( alex ); 16 | DECLARE_VAR( X ); 17 | DECLARE_VAR( G ); 18 | } 19 | 20 | void TestProlog() 21 | { 22 | using namespace tcalc; 23 | using namespace tcalc::container::list; 24 | using namespace tcalc::prolog; 25 | 26 | // test unification 27 | typedef Term< Value_boy, List< Value_bill, NullItem > > TermA; 28 | typedef Term< Value_boy, List< Value_frank, NullItem > > TermB; 29 | typedef Term< Value_boy, List< Value_X, NullItem > > TermX; 30 | typedef Term< Value_boy, List< Value_G, NullItem > > TermG; 31 | 32 | typedef Unify< TermA, NullItem, TermB, NullItem > Unified1; 33 | cout << Unified1::ret << endl; 34 | PrintMap< Unified1::ResultEnv >::Print(); 35 | 36 | typedef Unify< TermA, NullItem, TermA, NullItem > Unified2; 37 | cout << Unified2::ret << endl; 38 | PrintMap< Unified2::ResultEnv >::Print(); 39 | 40 | typedef Unify< TermA, NullItem, TermX, NullItem > Unified3; 41 | cout << Unified3::ret << endl; 42 | PrintMap< Unified3::ResultEnv >::Print(); 43 | 44 | typedef Unify< TermB, NullItem, TermX, Unified3::ResultEnv > Unified4; 45 | cout << Unified4::ret << endl; 46 | PrintMap< Unified4::ResultEnv >::Print(); 47 | 48 | typedef Unify< TermG, NullItem, TermX, NullItem > Unified5; 49 | cout << Unified5::ret << endl; 50 | PrintMap< Unified5::ResultEnv >::Print(); 51 | 52 | typedef List< Pair< Value_G, Value_frank >, NullItem > Env; 53 | typedef Unify< TermG, Env, TermX, NullItem > Unified6; 54 | cout << Unified6::ret << endl; 55 | PrintMap< Unified6::ResultEnv >::Print(); 56 | 57 | cout << "--------" << endl; 58 | 59 | // test search 60 | typedef Term< Value_child, List< Value_X, NullItem > > TermChildX; // child(X) 61 | typedef Term< Value_boy, List< Value_X, NullItem > > TermBoyX; // boy(X) 62 | typedef Term< Value_girl, List< Value_X, NullItem > > TermGirlX; // girl(X) 63 | typedef Term< Value_boy, List< Value_alex, NullItem > > TermBoyAlex; // boy(alex) 64 | typedef Term< Value_girl, List< Value_alice, NullItem > > TermGirlAlice; // girl(alice) 65 | typedef Term< Value_child, List< Value_G, NullItem > > TermChildG; // child(G) 66 | 67 | typedef Rule< TermBoyAlex, NullItem > RuleBoyAlex; // boy(alex) :- True 68 | typedef Rule< TermGirlAlice, NullItem > RuleGirlAlice; // girl(alice) :- True 69 | typedef Rule< TermChildX, List< TermBoyX, NullItem > > RuleChildBoy; // child(X) :- boy(x) 70 | typedef Rule< TermChildX, List< TermGirlX, NullItem > > RuleChildGirl; // child(X) :- girl(x) 71 | 72 | typedef List< RuleChildBoy, List< RuleChildGirl, 73 | List< RuleBoyAlex, List< RuleGirlAlice, NullItem > > > > AllRules; 74 | 75 | typedef SearchGoal< TermChildG, AllRules > Result; 76 | //typedef SearchGoal< TermBoyX, AllRules > Result; 77 | cout << Result::ret << endl; 78 | PrintMap< Result::ResultEnv >::Print(); 79 | } 80 | 81 | void TestList() 82 | { 83 | using namespace tcalc; 84 | using namespace tcalc::container::list; 85 | const int v = Add< Value, Value >::NextType::val; 86 | const int ret = Power< Div< Value, Value >::NextType, 8 >::NextType::val; 87 | 88 | typedef List< Value< int, 3 >, List< Value, List< Value, NullItem > > > FunnyList; 89 | typedef List< Value< int, 5 >, List< Value, List< Value, NullItem > > > FunnyList2; 90 | 91 | cout << ListLength< FunnyList >::val << endl; 92 | cout << Advance< FunnyList, 2 >::NextType::value_type::val << endl; 93 | 94 | //cout << Advance< typename PopBack< FunnyList >::NextType, 1 >::NextType::val << endl; 95 | //cout << Advance< typename PushBack< Value, FunnyList >::NextType, 2 >::NextType::val << endl; 96 | 97 | typedef InsertAt< FunnyList, Value, 2 >::NextType WithVal; 98 | WithVal::Print(); 99 | 100 | typedef Merge< FunnyList, FunnyList2 >::NextType MergedList; 101 | MergedList::Print(); 102 | 103 | static const int NUM_ITEMS = 7; 104 | typedef Generate< NUM_ITEMS >::NextType FirstList; 105 | typedef Generate< NUM_ITEMS, NUM_ITEMS / 2 >::NextType SecondList; 106 | 107 | typedef Merge< FirstList, SecondList >::NextType M; 108 | typedef MergeSort< M >::NextType Sorted; 109 | Sorted::Print(); 110 | 111 | typedef Map< Sorted, Add, Value >::NextType Plus100; 112 | Plus100::Print(); 113 | 114 | typedef Fold< Plus100, Add, Value >::NextType Folded; 115 | cout << Folded::val << endl; 116 | 117 | typedef Filter< Sorted, Less, Value >::NextType Filtered; 118 | Filtered::Print(); 119 | 120 | //typedef List< StringValue_1, NullItem > StringList; 121 | //StringList::Print(); 122 | 123 | //typedef typename FindMinimum< FunnyList2 >::NextType E; 124 | //typedef Search< FunnyList2, E > Found; 125 | //typedef typename EraseAtIndex< FunnyList2, Found::val >::NextType L2MinusMin; 126 | 127 | //typedef LowerBound< FunnyList2, Value< int, 2 > > LB; 128 | //cout << LB::val << endl; 129 | //typedef typename InsertAt< FunnyList, E, LB::val >::NextType L1PlusMin; 130 | //L1PlusMin::Print(); 131 | //typedef typename InsertAt< L1, E, LB::val >::NextType L1PlusMin; 132 | 133 | //L2MinusMin::Print(); 134 | 135 | typedef List< Value, List< Value, NullItem > > FL; 136 | typedef List< Value, NullItem > FL2; 137 | 138 | typedef LowerBound< FL, Value< int, 2 > > LBx; 139 | cout << LBx::val << endl; 140 | 141 | typedef MergeSorted< FunnyList, FunnyList2 >::NextType MS; 142 | MS::Print(); 143 | typedef MergeSort< MS >::NextType Sorted2; 144 | Sorted2::Print(); 145 | 146 | //cout << FindMinimum< MergedList >::NextType::val << endl; 147 | 148 | //cout << Advance< typename First< FunnyList, 2 >::NextType, 0 >::NextType::val << endl; 149 | 150 | //Advance< typename EraseAtIndex< FunnyList, 1 >::NextType, 0 >::NextType::Print(); 151 | 152 | cout << Search< FunnyList, Value< int, 1 > >::val << endl; 153 | 154 | //////// 155 | 156 | //typedef List< Value< int, 1 >, List< StringValue_1, NullItem > > ValueList; 157 | //ValueList::Print(); 158 | } 159 | 160 | void TestMap() 161 | { 162 | using namespace tcalc; 163 | using namespace tcalc::container::map; 164 | 165 | typedef NullItem Initial; 166 | typedef AddKey< Pair< tcalc::Value, tcalc::Value >, Initial >::NextType One; 167 | typedef AddKey< Pair< tcalc::Value, tcalc::Value >, One >::NextType ReplaceOne; 168 | typedef FindKey< tcalc::Value, ReplaceOne >::NextType FoundOne; 169 | cout << FoundOne::Value::val << endl; 170 | cout << ListLength< ReplaceOne >::val << endl; 171 | 172 | typedef AddKey< Pair< tcalc::Value, tcalc::Value >, One >::NextType Two; 173 | cout << ListLength< Two >::val << endl; 174 | 175 | typedef AddKey< Pair< tcalc::Value, tcalc::Value >, Two >::NextType Three; 176 | typedef AddKey< Pair< tcalc::Value, tcalc::Value >, Three >::NextType ReplaceThree; 177 | cout << ListLength< ReplaceThree >::val << endl; 178 | 179 | typedef EraseKey< tcalc::Value, Three >::NextType Erased; 180 | cout << ListLength< Erased >::val << endl; 181 | } 182 | 183 | int main() 184 | { 185 | //TestList(); 186 | //TestMap(); 187 | TestProlog(); 188 | return 0; 189 | } 190 | --------------------------------------------------------------------------------