nibli_semantics/
dictionary.rs1pub struct LexiconSchema;
11
12impl LexiconSchema {
13 pub fn get_arity(word: &str) -> Option<usize> {
18 nibli_lexicon::get_arity(word)
19 }
20
21 pub fn get_arity_or_default(word: &str) -> usize {
24 Self::get_arity(word).unwrap_or(2)
25 }
26
27 pub fn injected_arity(relation: &str, provided: usize) -> Result<usize, String> {
35 match Self::get_arity(relation) {
36 Some(a) if provided > a => Err(format!(
37 "{relation:?} has arity {a}, but {provided} arguments were supplied — \
38 refusing to silently drop the extras"
39 )),
40 Some(a) => Ok(a),
41 None => Ok(provided),
42 }
43 }
44}
45
46#[cfg(test)]
47mod tests {
48 use super::*;
49
50 #[test]
53 fn test_get_arity_known_alias_goes() {
54 let arity = LexiconSchema::get_arity("goes");
56 assert!(arity.is_some());
57 assert_eq!(arity.unwrap(), 5);
58 }
59
60 #[test]
61 fn test_get_arity_known_alias_dog() {
62 let arity = LexiconSchema::get_arity("dog");
64 assert!(arity.is_some());
65 assert_eq!(arity.unwrap(), 2);
66 }
67
68 #[test]
69 fn test_get_arity_known_alias_loves() {
70 let arity = LexiconSchema::get_arity("loves");
72 assert!(arity.is_some());
73 assert_eq!(arity.unwrap(), 2);
74 }
75
76 #[test]
77 fn test_get_arity_known_alias_talks() {
78 let arity = LexiconSchema::get_arity("talks");
80 assert!(arity.is_some());
81 assert_eq!(arity.unwrap(), 4);
82 }
83
84 #[test]
85 fn test_gismu_never_resolves() {
86 assert_eq!(LexiconSchema::get_arity("klama"), None);
89 assert_eq!(LexiconSchema::get_arity("gerku"), None);
90 }
91
92 #[test]
93 fn test_get_arity_unknown_word_returns_none() {
94 assert_eq!(LexiconSchema::get_arity("zzzzz"), None);
95 }
96
97 #[test]
98 fn test_get_arity_empty_string_returns_none() {
99 assert_eq!(LexiconSchema::get_arity(""), None);
100 }
101
102 #[test]
103 fn test_get_arity_cmavo_not_in_dict() {
104 assert_eq!(LexiconSchema::get_arity("lo"), None);
106 assert_eq!(LexiconSchema::get_arity("cu"), None);
107 }
108
109 #[test]
112 fn test_get_arity_or_default_known_alias() {
113 assert_eq!(LexiconSchema::get_arity_or_default("goes"), 5);
114 }
115
116 #[test]
117 fn test_get_arity_or_default_unknown_returns_two() {
118 assert_eq!(LexiconSchema::get_arity_or_default("xyzzy"), 2);
119 }
120
121 #[test]
122 fn test_get_arity_or_default_empty_returns_two() {
123 assert_eq!(LexiconSchema::get_arity_or_default(""), 2);
124 }
125
126 #[test]
127 fn test_get_arity_english_alias() {
128 assert_eq!(LexiconSchema::get_arity("goes"), Some(5));
131 assert_eq!(LexiconSchema::get_arity("dog"), Some(2));
132 assert_eq!(LexiconSchema::get_arity_or_default("goes"), 5);
133 }
134
135 #[test]
138 fn test_various_alias_arities() {
139 let checks = vec![
141 ("cat", 2), ("big", 3), ("fast", 2), ("person", 1), ("name", 3), ("gives", 3), ("product", 3), ("sum", 3), ("quantity", 3), ];
151 for (word, expected) in checks {
152 let actual = LexiconSchema::get_arity(word);
153 assert!(actual.is_some(), "expected {} to resolve", word);
154 assert_eq!(
155 actual.unwrap(),
156 expected,
157 "{} should have arity {}, got {}",
158 word,
159 expected,
160 actual.unwrap()
161 );
162 }
163 }
164
165 #[test]
166 fn test_unknown_word_arity_is_none() {
167 assert_eq!(LexiconSchema::get_arity("brivla"), None);
169 }
170
171 #[test]
172 fn test_injected_arity_policy() {
173 assert_eq!(LexiconSchema::injected_arity("product", 3), Ok(3));
175 assert_eq!(LexiconSchema::injected_arity("product", 1), Ok(3));
176 let e = LexiconSchema::injected_arity("product", 4).unwrap_err();
177 assert!(e.contains("arity 3") && e.contains("4 arguments"), "{e}");
178 assert_eq!(LexiconSchema::injected_arity("zzz_unknown", 1), Ok(1));
180 assert_eq!(LexiconSchema::injected_arity("zzz_unknown", 5), Ok(5));
181 }
182
183 #[test]
184 fn test_get_arity_consistent_with_default() {
185 let word = "goes";
187 let arity = LexiconSchema::get_arity(word).unwrap();
188 let default_arity = LexiconSchema::get_arity_or_default(word);
189 assert_eq!(arity, default_arity);
190 }
191}