Generates suffix-based stem variants for a set of symbols. For each symbol, tries common suffixes (e.g. "authenticate" generates "authentication", "authenticator", "authenticated"). Only produces variants that differ from the original and from other symbols.
(symbols: &[String])
| 802 | /// "authentication", "authenticator", "authenticated"). Only produces |
| 803 | /// variants that differ from the original and from other symbols. |
| 804 | fn generate_stem_variants(symbols: &[String]) -> Vec<String> { |
| 805 | /// Common English derivational suffixes, ordered longest-first so that |
| 806 | /// stripping "ation" is preferred over "ion" when both match. |
| 807 | const SUFFIX_PAIRS: &[(&str, &[&str])] = &[ |
| 808 | ("tion", &["te", "tor", "t", "ting"]), |
| 809 | ("sion", &["de", "d", "ding"]), |
| 810 | ("ment", &["", "ing", "ed"]), |
| 811 | ("ness", &["", "ly"]), |
| 812 | ("ing", &["", "e", "ion", "ment"]), |
| 813 | ("ed", &["", "e", "ing", "ion"]), |
| 814 | ("er", &["", "e", "ing", "ed"]), |
| 815 | ("or", &["", "e", "ion"]), |
| 816 | ("ly", &["", "ness"]), |
| 817 | ("ize", &["ization", "ized"]), |
| 818 | ("ise", &["isation", "ised"]), |
| 819 | ("ate", &["ation", "ator", "ated", "ating"]), |
| 820 | ("ify", &["ification", "ified"]), |
| 821 | ]; |
| 822 | |
| 823 | let existing: HashSet<String> = symbols.iter().map(|s| s.to_lowercase()).collect(); |
| 824 | let mut variants: Vec<String> = Vec::new(); |
| 825 | let mut seen: HashSet<String> = HashSet::new(); |
| 826 | |
| 827 | for symbol in symbols { |
| 828 | let lower = symbol.to_lowercase(); |
| 829 | if lower.len() < 4 { |
| 830 | continue; |
| 831 | } |
| 832 | |
| 833 | for &(suffix, replacements) in SUFFIX_PAIRS { |
| 834 | if let Some(stem) = lower.strip_suffix(suffix) { |
| 835 | if stem.len() < 2 { |
| 836 | continue; |
| 837 | } |
| 838 | for &replacement in replacements { |
| 839 | let variant = format!("{stem}{replacement}"); |
| 840 | if variant.len() >= 3 |
| 841 | && !existing.contains(&variant) |
| 842 | && seen.insert(variant.clone()) |
| 843 | { |
| 844 | variants.push(variant); |
| 845 | } |
| 846 | } |
| 847 | break; // only strip the first matching suffix |
| 848 | } |
| 849 | } |
| 850 | } |
| 851 | |
| 852 | variants |
| 853 | } |
| 854 | |
| 855 | /// Boosts candidates whose file contains multiple query terms. |
| 856 | /// |