spacepaste

  1.  
  2. $ ./trie_binary
  3. ----------------------------------------------------------------------->called init_aux() at line 348 from vcpu/../Shell/builtins/libstring.h
  4. ----------------------------------------------------------------------->called init_env() at line 327 from vcpu/../Shell/builtins/libstring.h
  5. ----------------------------------------------------------------------->called init_argX() at line 336 from vcpu/../Shell/builtins/libstring.h
  6. segment.string = 1
  7. branch_index = 0
  8. segments_curr = 0x55608c96c360
  9. segments_prev = 0x55608c96c360
  10. branch_index = 0
  11. index = 1
  12. level = 0
  13. key[level] = 1
  14. pCrawl = 0x55608c96c360
  15. pCrawl->children = 0x55608c96c360
  16. pCrawl->children[index] = 0x55608c96d420
  17. pCrawl->next_count = 2
  18. pCrawl->next = 0x55608c96d3a0
  19. pCrawl->branch = true
  20. pCrawl->next[branch_index] = 0x55608c96c460
  21. modifying root
  22. pCrawl->branch = true
  23. segments_curr = 0x55608c96c460
  24. segments_prev = 0x55608c96c360
  25. branches = true
  26. creating backtrack reference
  27. pCrawl = 0x55608c96c260
  28. segments_curr = 0x55608c96c460
  29. segments_prev = 0x55608c96c360
  30. level = 0
  31. index = 1
  32. idx = 0
  33. key = 12456
  34. successfull
  35. idx = 0
  36. result1 = true
  37. idx = 1
  38. segment.string = 2
  39. branch_index = 0
  40. segments_curr = 0x55608c96c460
  41. segments_prev = 0x55608c96c460
  42. branch_index = 0
  43. index = 2
  44. level = 0
  45. key[level] = 2
  46. pCrawl = 0x55608c96c460
  47. pCrawl->children = 0x55608c96c460
  48. pCrawl->children[index] = 0x55608c96d5a0
  49. pCrawl->next_count = 1
  50. pCrawl->next = 0x55608c96d520
  51. pCrawl->branch = false
  52. pCrawl->next[branch_index] = 0x55608c96c560
  53. modifying root
  54. pCrawl->branch = false
  55. segments_curr = 0x55608c96c560
  56. segments_prev = 0x55608c96c460
  57. branches = false
  58. idx = 1
  59. result1 = true
  60. idx = 2
  61. segment.string = 4
  62. branch_index = 0
  63. segments_curr = 0x55608c96c560
  64. segments_prev = 0x55608c96c560
  65. branch_index = 0
  66. index = 4
  67. level = 0
  68. key[level] = 4
  69. pCrawl = 0x55608c96c560
  70. pCrawl->children = 0x55608c96c560
  71. pCrawl->children[index] = (nil)
  72. not found
  73. segments_curr = 0x55608c96c560
  74. segments_prev = 0x55608c96c560
  75. branches = false
  76. idx = 2
  77. result1 = false
  78. loading last backtrack reference
  79. pCrawl = 0x55608c96cee0
  80. segments = 0x55608c96c560
  81. level = 3
  82. index = 4
  83. idx = 2
  84. key = 12456
  85. Backtrack_node->pCrawl = 0x55608c96c260
  86. Backtrack_node->segments = 0x55608c96c360
  87. Backtrack_node->level = 0
  88. Backtrack_node->index = 1
  89. Backtrack_node->idx = 0
  90. Backtrack_node->key = 12456
  91. segment.string = 1
  92. branch_index = 1
  93. segments_curr = 0x55608c96c360
  94. segments_prev = 0x55608c96c360
  95. branch_index = 1
  96. index = 1
  97. level = 0
  98. key[level] = 1
  99. pCrawl = 0x55608c96c360
  100. pCrawl->children = 0x55608c96c360
  101. pCrawl->children[index] = 0x55608c96d420
  102. pCrawl->next_count = 2
  103. pCrawl->next = 0x55608c96d3a0
  104. pCrawl->branch = true
  105. pCrawl->next[branch_index] = 0x55608c96c860
  106. modifying root
  107. pCrawl->branch = true
  108. segments_curr = 0x55608c96c860
  109. segments_prev = 0x55608c96c360
  110. branches = true
  111. creating backtrack reference
  112. pCrawl = 0x55608c96c260
  113. segments_curr = 0x55608c96c860
  114. segments_prev = 0x55608c96c360
  115. level = 0
  116. index = 1
  117. idx = 0
  118. key = 12456
  119. successfull
  120. idx = 0
  121. result1 = true
  122. idx = 1
  123. segment.string = 2
  124. branch_index = 0
  125. segments_curr = 0x55608c96c860
  126. segments_prev = 0x55608c96c860
  127. branch_index = 0
  128. index = 2
  129. level = 0
  130. key[level] = 2
  131. pCrawl = 0x55608c96c860
  132. pCrawl->children = 0x55608c96c860
  133. pCrawl->children[index] = 0x55608c96e060
  134. pCrawl->next_count = 1
  135. pCrawl->next = 0x55608c96cce0
  136. pCrawl->branch = false
  137. pCrawl->next[branch_index] = 0x55608c96c960
  138. modifying root
  139. pCrawl->branch = false
  140. segments_curr = 0x55608c96c960
  141. segments_prev = 0x55608c96c860
  142. branches = false
  143. idx = 1
  144. result1 = true
  145. idx = 2
  146. segment.string = 4
  147. branch_index = 0
  148. segments_curr = 0x55608c96c960
  149. segments_prev = 0x55608c96c960
  150. branch_index = 0
  151. index = 4
  152. level = 0
  153. key[level] = 4
  154. pCrawl = 0x55608c96c960
  155. pCrawl->children = 0x55608c96c960
  156. pCrawl->children[index] = 0x55608c96e1e0
  157. pCrawl->next_count = 1
  158. pCrawl->next = 0x55608c96e160
  159. pCrawl->branch = false
  160. pCrawl->next[branch_index] = 0x55608c96ca60
  161. modifying root
  162. pCrawl->branch = false
  163. segments_curr = 0x55608c96ca60
  164. segments_prev = 0x55608c96c960
  165. branches = false
  166. idx = 2
  167. result1 = true
  168. idx = 3
  169. segment.string = 5
  170. branch_index = 0
  171. segments_curr = 0x55608c96ca60
  172. segments_prev = 0x55608c96ca60
  173. branch_index = 0
  174. index = 5
  175. level = 0
  176. key[level] = 5
  177. pCrawl = 0x55608c96ca60
  178. pCrawl->children = 0x55608c96ca60
  179. pCrawl->children[index] = 0x55608c96e360
  180. pCrawl->next_count = 1
  181. pCrawl->next = 0x55608c96e2e0
  182. pCrawl->branch = false
  183. pCrawl->next[branch_index] = 0x55608c96cb60
  184. modifying root
  185. pCrawl->branch = false
  186. segments_curr = 0x55608c96cb60
  187. segments_prev = 0x55608c96ca60
  188. branches = false
  189. idx = 3
  190. result1 = true
  191. idx = 4
  192. segment.string = 6
  193. branch_index = 0
  194. segments_curr = 0x55608c96cb60
  195. segments_prev = 0x55608c96cb60
  196. branch_index = 0
  197. index = 6
  198. level = 0
  199. key[level] = 6
  200. pCrawl = 0x55608c96cb60
  201. pCrawl->children = 0x55608c96cb60
  202. pCrawl->children[index] = 0x55608c96e4e0
  203. pCrawl->next_count = 1
  204. pCrawl->next = 0x55608c96e460
  205. pCrawl->branch = false
  206. pCrawl->next[branch_index] = (nil)
  207. pCrawl->branch = false
  208. segments_curr = 0x55608c96cb60
  209. segments_prev = 0x55608c96cb60
  210. branches = false
  211. idx = 4
  212. result1 = true
  213. idx = 5
  214. 12456 --- Present in trie
  215. $ cat trie_binary.c
  216. // C implementation of search and insert operations
  217. // on Trie
  218. #include <stdio.h>
  219. #include <stdlib.h>
  220. #include <string.h>
  221. #include <stdbool.h>
  222. #include "../Shell/builtins/printfmacro.h"
  223. #include "../Shell/builtins/regex_str.h"
  224. // backtracking history
  225. // A C program to demonstrate linked list based implementation of queue
  226. // A linked list (LL) node to store a queue entry
  227. struct Backtrack_QNode
  228. {
  229. struct TrieNode *pCrawl;
  230. struct TrieNode *segments;
  231. int level;
  232. int index;
  233. int idx;
  234. const char * key;
  235. struct Backtrack_QNode *next;
  236. };
  237. // The queue, front stores the front node of LL and rear stores ths
  238. // last node of LL
  239. struct Backtrack_Queue
  240. {
  241. struct Backtrack_QNode *front, *rear;
  242. };
  243. // A utility function to create a new linked list node.
  244. struct Backtrack_QNode* Backtrack_newNode(struct TrieNode *pCrawl, struct TrieNode *segments, int level, int index, int idx, const char * key)
  245. {
  246. struct Backtrack_QNode *temp = (struct Backtrack_QNode*)malloc(sizeof(struct Backtrack_QNode));
  247. temp->pCrawl = pCrawl;
  248. temp->segments = segments;
  249. temp->level = level;
  250. temp->index = index;
  251. temp->idx = idx;
  252. temp->key = key;
  253. temp->next = NULL;
  254. return temp;
  255. }
  256. // A utility function to create an empty queue
  257. struct Backtrack_Queue *Backtrack_createQueue()
  258. {
  259. struct Backtrack_Queue *q = (struct Backtrack_Queue*)malloc(sizeof(struct Backtrack_Queue));
  260. q->front = q->rear = NULL;
  261. return q;
  262. }
  263. void Backtrack_store_asm(struct Backtrack_Queue **qq, struct TrieNode *pCrawl, struct TrieNode *segments, int level, int index, int idx, const char * key)
  264. {
  265. if (*qq == NULL)
  266. *qq = Backtrack_createQueue();
  267. // Create a new LL node
  268. struct Backtrack_QNode *temp = Backtrack_newNode(pCrawl, segments, level, index, idx, key);
  269. // If queue is empty, then new node is front and rear both
  270. if ((*qq)->rear == NULL)
  271. {
  272. (*qq)->front = (*qq)->rear = temp;
  273. return;
  274. }
  275. // Add the new node at the end of queue and change rear
  276. temp->next = (*qq)->rear;
  277. (*qq)->rear = temp;
  278. }
  279. struct Backtrack_QNode * Backtrack_load_asm(struct Backtrack_Queue **qq)
  280. {
  281. if ((*qq) == NULL)
  282. return NULL;
  283. // If queue is empty, return NULL.
  284. if ((*qq)->rear == NULL)
  285. return NULL;
  286. // Store previous front and move front one node ahead
  287. struct Backtrack_QNode *temp = (*qq)->rear;
  288. (*qq)->rear = (*qq)->rear->next;
  289. // If front becomes NULL, then change rear also as NULL
  290. if ((*qq)->rear == NULL)
  291. (*qq)->front = NULL;
  292. return temp;
  293. }
  294. #define ARRAY_SIZE(a) sizeof(a)/sizeof(a[0])
  295. // Alphabet size (# of symbols)
  296. #define ALPHABET_SIZE (26)
  297. // Converts key current character into index
  298. // use only 'a' through 'z' and lower case
  299. #define CHAR_TO_INDEX(c) ((int)c - (int)'a')
  300. #define INT_TO_INDEX(c) ((int)c - (int)'0')
  301. // trie node
  302. struct TrieNode
  303. {
  304. struct TrieNode *children[ALPHABET_SIZE];
  305. int * idx;
  306. int count;
  307. bool branch;
  308. // isEndOfWord is true if the node represents
  309. // end of a word
  310. bool isEndOfWord;
  311. struct TrieNode ** next;
  312. int next_count;
  313. };
  314. bool is_branch = true;
  315. bool is_not_branch = false;
  316. // Returns new trie node (initialized to NULLs)
  317. struct TrieNode *getNode(void)
  318. {
  319. struct TrieNode *pNode = NULL;
  320. pNode = (struct TrieNode *)malloc(sizeof(struct TrieNode));
  321. if (pNode)
  322. {
  323. int i;
  324. pNode->isEndOfWord = false;
  325. pNode->idx = NULL;
  326. pNode->next = NULL;
  327. pNode->count = 0;
  328. for (i = 0; i < ALPHABET_SIZE; i++)
  329. pNode->children[i] = NULL;
  330. }
  331. return pNode;
  332. }
  333. // If not present, inserts key into trie
  334. // If the key is prefix of trie node, just marks leaf node
  335. void insert(struct TrieNode *root, const char *key, int dest_idx, struct TrieNode *next)
  336. {
  337. int level;
  338. int length = strlen(key);
  339. int index;
  340. struct TrieNode *pCrawl = root;
  341. // pi(dest_idx)
  342. for (level = 0; level < length; level++)
  343. {
  344. // pi(level);
  345. // pc(key[level])
  346. str_new(ch);
  347. str_insert_char(ch, key[level]);
  348. if (ch.type & STR_TYPE_DIGIT) index = INT_TO_INDEX(key[level]);
  349. else if (ch.type & STR_TYPE_ALPHABETIC) index = CHAR_TO_INDEX(key[level]);
  350. str_free(ch)
  351. // pi(index)
  352. // pp(pCrawl->children[index])
  353. if (!pCrawl->children[index]) {
  354. pCrawl->children[index] = getNode();
  355. }
  356. if (level == length-1) {
  357. // pp(pCrawl->children[index])
  358. // pp(pCrawl->children[index]->idx)
  359. pCrawl->children[index]->next_count++;
  360. if (!pCrawl->children[index]->next) {
  361. pCrawl->children[index]->next = malloc(sizeof(int*)*pCrawl->children[index]->next_count);
  362. // pp(pCrawl->children[index]->idx)
  363. }
  364. else {
  365. pCrawl->children[index]->next = realloc(pCrawl->children[index]->next, sizeof(int*)*pCrawl->children[index]->next_count);
  366. }
  367. pCrawl->children[index]->next[pCrawl->children[index]->next_count-1] = next;
  368. if (pCrawl->children[index]->next_count > 1) pCrawl->children[index]->branch = true;
  369. pCrawl->children[index]->count++;
  370. if (!pCrawl->children[index]->idx) {
  371. pCrawl->children[index]->idx = malloc(sizeof(int*)*pCrawl->children[index]->count);
  372. // pp(pCrawl->children[index]->idx)
  373. }
  374. else {
  375. pCrawl->children[index]->idx = realloc(pCrawl->children[index]->idx, sizeof(int*)*pCrawl->children[index]->count);
  376. }
  377. pCrawl->children[index]->idx[pCrawl->children[index]->count-1] = dest_idx;
  378. // pi(pCrawl->children[index]->idx[pCrawl->children[index]->count-1])
  379. }
  380. pCrawl = pCrawl->children[index];
  381. }
  382. // mark last node as leaf
  383. pCrawl->isEndOfWord = true;
  384. }
  385. // Returns true if key presents in trie, else false
  386. bool search(struct TrieNode **root, const char *key, int idx, bool * branches, int branch_index)
  387. {
  388. int level;
  389. int length = strlen(key);
  390. int index;
  391. struct TrieNode *pCrawl = *root;
  392. // pi(idx);
  393. for (level = 0; level < length; level++)
  394. {
  395. str_new(ch);
  396. str_insert_char(ch, key[level]);
  397. if (ch.type & STR_TYPE_DIGIT) index = INT_TO_INDEX(key[level]);
  398. else if (ch.type & STR_TYPE_ALPHABETIC) index = CHAR_TO_INDEX(key[level]);
  399. str_free(ch)
  400. pi(branch_index)
  401. pi(index)
  402. pi(level)
  403. pc(key[level])
  404. pp(pCrawl)
  405. pp(pCrawl->children)
  406. pp(pCrawl->children[index])
  407. if (!pCrawl->children[index]) {
  408. index = CHAR_TO_INDEX('x');
  409. if (!pCrawl->children[index]) {
  410. puts("not found");
  411. return false;
  412. }
  413. }
  414. pCrawl = pCrawl->children[index];
  415. pi(pCrawl->next_count);
  416. if (branch_index > pCrawl->next_count-1) {
  417. puts("error, branch index is greater than branch count");
  418. abort();
  419. }
  420. pp(pCrawl->next);
  421. pb(pCrawl->branch);
  422. *branches = pCrawl->branch;
  423. if (pCrawl->next) {
  424. pp(pCrawl->next[branch_index]);
  425. if (pCrawl->next[branch_index]) {
  426. puts("modifying root");
  427. *root = pCrawl->next[branch_index];
  428. }
  429. }
  430. }
  431. // pi(pCrawl->count)
  432. bool final_match = false;
  433. for (int i = 0; i < pCrawl->count; i++) {
  434. // pi(pCrawl->idx[i])
  435. if (pCrawl->idx[i] == idx) final_match = true;
  436. }
  437. // pb(final_match)
  438. pb(pCrawl->branch);
  439. return (pCrawl != NULL && pCrawl->isEndOfWord && final_match);
  440. }
  441. // Returns true if key presents in trie, else false
  442. bool search_segmented(struct TrieNode *root, struct TrieNode *segments, const char *key)
  443. {
  444. int level;
  445. int length = strlen(key);
  446. int index;
  447. int branch_index = 0;
  448. struct TrieNode *pCrawl = root;
  449. str_new(segment);
  450. int idx = 0;
  451. int undo = 0;
  452. bool next_reload = false;
  453. struct Backtrack_Queue * Backtrack_queue = NULL;
  454. for (level = 0; level < length; level++)
  455. {
  456. if (next_reload == true) {
  457. puts("loading last backtrack reference");
  458. struct Backtrack_QNode * Backtrack_node = NULL; \
  459. Backtrack_node = Backtrack_load_asm(&Backtrack_queue);
  460. if (Backtrack_node) {
  461. pp(pCrawl)
  462. pp(segments)
  463. pi(level)
  464. pi(index)
  465. pi(idx)
  466. ps(key)
  467. pp(Backtrack_node->pCrawl)
  468. pp(Backtrack_node->segments)
  469. pi(Backtrack_node->level)
  470. pi(Backtrack_node->index)
  471. pi(Backtrack_node->idx)
  472. ps(Backtrack_node->key)
  473. for (int i = 0; i < undo; i++) {
  474. str_undo_(segment);
  475. }
  476. undo = 0;
  477. pCrawl = Backtrack_node->pCrawl;
  478. segments = Backtrack_node->segments;
  479. level = Backtrack_node->level;
  480. index = Backtrack_node->index;
  481. idx = Backtrack_node->idx;
  482. key = Backtrack_node->key;
  483. branch_index++;
  484. }
  485. }
  486. str_new(ch);
  487. str_insert_char(ch, key[level]);
  488. if (ch.type & STR_TYPE_DIGIT) index = INT_TO_INDEX(key[level]);
  489. else if (ch.type & STR_TYPE_ALPHABETIC) index = CHAR_TO_INDEX(key[level]);
  490. str_free(ch)
  491. str_insert_char(segment, key[level]);
  492. ps(segment.string);
  493. // pp(segments)
  494. bool branches = false;
  495. pi(branch_index);
  496. struct TrieNode *segments_prev = segments, *segments_curr = segments;
  497. pp(segments_curr)
  498. pp(segments_prev)
  499. bool result1 = search(&segments, segment.string, idx, &branches, branch_index);
  500. segments_curr = segments;
  501. pp(segments_curr)
  502. pp(segments_prev)
  503. pb(branches)
  504. if (branches) {
  505. // store a backtrack reference to this branch
  506. puts("creating backtrack reference");
  507. pp(pCrawl)
  508. pp(segments_curr)
  509. pp(segments_prev)
  510. pi(level)
  511. pi(index)
  512. pi(idx)
  513. ps(key)
  514. Backtrack_store_asm(&Backtrack_queue, pCrawl, segments_prev, level, index, idx, key);
  515. puts("successfull");
  516. }
  517. // pp(segments)
  518. pi(idx)
  519. pb(result1);
  520. undo++;
  521. next_reload = false;
  522. if (result1) {
  523. str_reset(segment);
  524. idx++;
  525. undo = 0;
  526. branch_index = 0;
  527. }
  528. else {
  529. next_reload = true;
  530. continue;
  531. }
  532. // sleep(5);
  533. pi(idx)
  534. if (!pCrawl->children[index]) {
  535. index = CHAR_TO_INDEX('x');
  536. if (!pCrawl->children[index]) return false;
  537. }
  538. pCrawl = pCrawl->children[index];
  539. }
  540. str_free(segment);
  541. return (pCrawl != NULL && pCrawl->isEndOfWord);
  542. }
  543. #define isp(root, segments, c) printf("%s --- %s\n", c, output[search_segmented(root, segments, c)] )
  544. // Driver
  545. int main()
  546. {
  547. char output[][32] = {"Not present in trie", "Present in trie"};
  548. /*
  549. // Construct trie
  550. insert(segments, "0011", 0, segments1);
  551. pp(segments->next)
  552. insert(segments1, "001", 1, NULL);
  553. insert(segments1, "0", 2, NULL);
  554. insert(segments1, "0", 3, NULL);
  555. insert(root, "001100100", 0, NULL);
  556. // Search for different keys
  557. isp(root, segments, "001100100");
  558. */
  559. // Construct trie
  560. /* shall aim to be equivilant to this
  561. rule_1 ::= "1" "0";
  562. rule_2 ::= "0" "1";
  563. rule_3 ::= "0" "0";
  564. */
  565. // rule 1
  566. // when adding a new rule indexing resets to 0
  567. struct TrieNode *root = getNode();
  568. struct TrieNode *sub_root = getNode();
  569. struct TrieNode *rule_1 = getNode();
  570. struct TrieNode *rule_2 = getNode();
  571. struct TrieNode *rule_3 = getNode();
  572. struct TrieNode *rule_4 = getNode();
  573. struct TrieNode *rule_5 = getNode();
  574. struct TrieNode *rule_6 = getNode();
  575. struct TrieNode *rule_7 = getNode();
  576. struct TrieNode *rule_8 = getNode();
  577. insert(root, "12356", 0, NULL);
  578. insert(sub_root, "1", 0, rule_1);
  579. insert(rule_1, "2", 1, rule_2);
  580. insert(rule_2, "3", 2, rule_3);
  581. insert(rule_3, "5", 3, rule_4);
  582. insert(rule_4, "6", 4, NULL);
  583. insert(root, "12456", 0, NULL);
  584. insert(sub_root, "1", 0, rule_5);
  585. insert(rule_5, "2", 1, rule_6);
  586. insert(rule_6, "4", 2, rule_7);
  587. insert(rule_7, "5", 3, rule_8);
  588. insert(rule_8, "6", 4, NULL);
  589. // Search for different keys
  590. // isp(root, sub_root, "12356");
  591. isp(root, sub_root, "12456");
  592. // isp(root, sub_root, "12356");
  593. return 0;
  594. }
  595. /*
  596. adding rule 1: segments [0, 1, 0] root [010]
  597. adding rule 2: segments [0, 1, 1] root [011]
  598. segment.string = 0
  599. result = true
  600. segment.string = 1
  601. result = true
  602. segment.string = 0
  603. result = false
  604. 010 --- Present in trie
  605. segment.string = 0
  606. result = true
  607. segment.string = 1
  608. result = true
  609. segment.string = 1
  610. result = true
  611. 011 --- Present in trie
  612. */
  613.