technician1 commited on
Commit
1df04f3
·
1 Parent(s): a18eebf

Upload 2 files

Browse files
Files changed (1) hide show
  1. ChatIPC.cpp +110 -2
ChatIPC.cpp CHANGED
@@ -16,6 +16,7 @@
16
  #include <unordered_map>
17
  #include <unordered_set>
18
  #include <vector>
 
19
 
20
  #ifdef _OPENMP
21
  #include <omp.h>
@@ -308,13 +309,108 @@ static std::vector<std::string> tokenize_whitespace(const std::string &s){
308
  return out;
309
  }
310
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311
  static std::vector<std::string> tokenize_others(const std::string &s) {
 
 
 
 
 
 
 
 
 
 
312
  std::vector<std::string> out;
313
  std::string cur;
314
 
 
315
  auto flush = [&]() {
316
  if (!cur.empty()) {
317
- out.push_back(cur);
 
 
 
318
  cur.clear();
319
  }
320
  };
@@ -323,6 +419,7 @@ static std::vector<std::string> tokenize_others(const std::string &s) {
323
  unsigned char uc = static_cast<unsigned char>(s[i]);
324
  char ch = static_cast<char>(uc);
325
 
 
326
  if (ch == '_' || ch == '-' || ch == '/' || std::isspace(uc)) {
327
  flush();
328
  continue;
@@ -341,7 +438,18 @@ static std::vector<std::string> tokenize_others(const std::string &s) {
341
  camel_boundary = prev_lower_or_digit || (prev_upper && next_lower);
342
  }
343
 
344
- if (camel_boundary) {
 
 
 
 
 
 
 
 
 
 
 
345
  flush();
346
  }
347
 
 
16
  #include <unordered_map>
17
  #include <unordered_set>
18
  #include <vector>
19
+ #include <string>
20
 
21
  #ifdef _OPENMP
22
  #include <omp.h>
 
309
  return out;
310
  }
311
 
312
+ // Static helper to check dictionary presence using your existing pos cache
313
+ static inline bool check_dictionary(const std::string &word) {
314
+ return !dictionary_pos_for_token(word).empty();
315
+ }
316
+
317
+ // Morphological lemmatizer to convert sub-tokens to their dictionary-defined base form.
318
+ // Returns std::optional<std::string>: contains the valid base form if found in the dictionary,
319
+ // or std::nullopt if the token has no definition and should be ignored.
320
+ static std::optional<std::string> get_valid_base_form(const std::string &word) {
321
+ if (word.empty()) return std::nullopt;
322
+
323
+ // 1. BEFORE extracting/stemming, check if the original form is already in the dictionary
324
+ if (check_dictionary(word)) {
325
+ return word;
326
+ }
327
+
328
+ // 2. Continuous verb form (-ing)
329
+ if (word.length() > 3 && word.substr(word.length() - 3) == "ing") {
330
+ // e.g., playing -> play
331
+ std::string base1 = word.substr(0, word.length() - 3);
332
+ if (check_dictionary(base1)) return base1;
333
+
334
+ // e.g., making -> make
335
+ std::string base2 = base1 + "e";
336
+ if (check_dictionary(base2)) return base2;
337
+
338
+ // e.g., running -> run (doubled consonant check)
339
+ if (base1.length() >= 2 && base1.back() == base1[base1.length() - 2]) {
340
+ std::string base3 = base1.substr(0, base1.length() - 1);
341
+ if (check_dictionary(base3)) return base3;
342
+ }
343
+ }
344
+
345
+ // 3. Past tense / Participle form (-ed)
346
+ if (word.length() > 2 && word.substr(word.length() - 2) == "ed") {
347
+ // e.g., baked -> bake
348
+ std::string base1 = word.substr(0, word.length() - 1);
349
+ if (check_dictionary(base1)) return base1;
350
+
351
+ // e.g., played -> play
352
+ std::string base2 = word.substr(0, word.length() - 2);
353
+ if (check_dictionary(base2)) return base2;
354
+
355
+ // e.g., hopped -> hop (doubled consonant check)
356
+ if (base2.length() >= 2 && base2.back() == base2[base2.length() - 2]) {
357
+ std::string base3 = base2.substr(0, base2.length() - 1);
358
+ if (check_dictionary(base3)) return base3;
359
+ }
360
+ }
361
+
362
+ // 4. Plural / 3rd-person singular form (-ies -> -y)
363
+ if (word.length() > 3 && word.substr(word.length() - 3) == "ies") {
364
+ std::string base = word.substr(0, word.length() - 3) + "y";
365
+ if (check_dictionary(base)) return base;
366
+ }
367
+
368
+ // 5. Plural / 3rd-person singular form (-ves -> -f / -fe)
369
+ if (word.length() > 3 && word.substr(word.length() - 3) == "ves") {
370
+ std::string base1 = word.substr(0, word.length() - 3) + "f";
371
+ if (check_dictionary(base1)) return base1;
372
+
373
+ std::string base2 = word.substr(0, word.length() - 3) + "fe";
374
+ if (check_dictionary(base2)) return base2;
375
+ }
376
+
377
+ // 6. Plural form (-es)
378
+ if (word.length() > 2 && word.substr(word.length() - 2) == "es") {
379
+ std::string base = word.substr(0, word.length() - 2);
380
+ if (check_dictionary(base)) return base;
381
+ }
382
+
383
+ // 7. Plural form (-s)
384
+ if (word.length() > 1 && word.back() == 's' && word[word.length() - 2] != 's') {
385
+ std::string base = word.substr(0, word.length() - 1);
386
+ if (check_dictionary(base)) return base;
387
+ }
388
+
389
+ // No dictionary-defined base form found
390
+ return std::nullopt;
391
+ }
392
+
393
  static std::vector<std::string> tokenize_others(const std::string &s) {
394
+ // Step A: Check if the entire input string already has a dictionary definition.
395
+ if (check_dictionary(s)) {
396
+ std::string lower_s;
397
+ lower_s.reserve(s.size());
398
+ for (char c : s) {
399
+ lower_s.push_back(to_low(c));
400
+ }
401
+ return { lower_s };
402
+ }
403
+
404
  std::vector<std::string> out;
405
  std::string cur;
406
 
407
+ // Lambda to flush the accumulated token buffer, validate it, and add to output
408
  auto flush = [&]() {
409
  if (!cur.empty()) {
410
+ auto valid_base = get_valid_base_form(cur);
411
+ if (valid_base.has_value()) {
412
+ out.push_back(valid_base.value());
413
+ }
414
  cur.clear();
415
  }
416
  };
 
419
  unsigned char uc = static_cast<unsigned char>(s[i]);
420
  char ch = static_cast<char>(uc);
421
 
422
+ // Split on spaces, underscores, hyphens, and slashes
423
  if (ch == '_' || ch == '-' || ch == '/' || std::isspace(uc)) {
424
  flush();
425
  continue;
 
438
  camel_boundary = prev_lower_or_digit || (prev_upper && next_lower);
439
  }
440
 
441
+ // Split on transitions between alphabetical characters and digits (e.g., "book5read")
442
+ bool digit_boundary = false;
443
+ if (!cur.empty()) {
444
+ unsigned char prev = static_cast<unsigned char>(s[i - 1]);
445
+ bool prev_digit = std::isdigit(prev) != 0;
446
+ bool curr_digit = std::isdigit(uc) != 0;
447
+ if (prev_digit != curr_digit) {
448
+ digit_boundary = true;
449
+ }
450
+ }
451
+
452
+ if (camel_boundary || digit_boundary) {
453
  flush();
454
  }
455