1 | concepts. |
2 | |
3 | !include #1005279 // Str, concept, mergeStrs |
4 | !include #1005328 // searchConcept |
5 | |
6 | concept AThing { |
7 | new Ref thing; |
8 | |
9 | *() {} |
10 | *(Concept thing) { this.thing.set(thing); } |
11 | } |
12 | |
13 | concept DefiniteThing {} |
14 | |
15 | static AThing aThing(S name) { |
16 | ret uniqueConcept(AThing.class, "thing", concept(name)); |
17 | } |
18 | |
19 | // "main" has a number of "part"s. |
20 | concept HasMulti { |
21 | new Ref main; |
22 | new Ref part; |
23 | } |
24 | |
25 | // "main" has exactly "count" "part"s. |
26 | concept MultiCount { |
27 | new Ref main; |
28 | new Ref part; |
29 | int count; |
30 | } |
31 | |
32 | // "main" has a "part". |
33 | concept HasA { |
34 | new Ref main; |
35 | new Ref part; |
36 | } |
37 | |
38 | // "main" has "part". |
39 | concept Has { |
40 | new Ref main; |
41 | new Ref part; |
42 | } |
43 | |
44 | concept IsA { |
45 | new Ref thing; |
46 | new Ref type; |
47 | } |
48 | |
49 | concept TheXOfY { |
50 | new Ref x; |
51 | new Ref y; |
52 | } |
53 | |
54 | concept Question { |
55 | S originalText; |
56 | } |
57 | |
58 | concept OpenQuestion { |
59 | new Ref<Question> question; |
60 | } |
61 | |
62 | concept AnsweredQuestion { |
63 | new Ref<Question> question; |
64 | new Ref answer; |
65 | } |
66 | |
67 | concept ConceptList { |
68 | new RefL<Concept> list; |
69 | |
70 | *() {} |
71 | *(L l) { list.addAll_(l); } |
72 | |
73 | void addAll(L l) { |
74 | list.addAll(l); |
75 | } |
76 | } |
77 | |
78 | concept HowManyAreIn extends Question { |
79 | new Ref main; |
80 | new Ref part; |
81 | } |
82 | |
83 | concept DoesXHaveAY extends Question { |
84 | new Ref x; |
85 | new Ref y; |
86 | } |
87 | |
88 | concept WhatDoesXHave extends Question { |
89 | new Ref thing; |
90 | } |
91 | |
92 | concept Yes {} |
93 | concept No {} |
94 | |
95 | concept AXIsY { |
96 | new Ref x; |
97 | new Ref y; |
98 | } |
99 | |
100 | concept SomethingTo { |
101 | new Ref<Verb> verb; |
102 | } |
103 | |
104 | concept Verb { |
105 | new Ref<Str> str; |
106 | |
107 | public S toString() { |
108 | ret str(str.get()); |
109 | } |
110 | } |
111 | |
112 | concept Actually { |
113 | new Ref what; |
114 | } |
115 | |
116 | // end of concepts |
117 | |
118 | static void truly(Class c, O... params) { |
119 | truly(unique(c, params)); |
120 | } |
121 | |
122 | static void truly(Concept what) { |
123 | unique(Actually, +what); |
124 | } |
125 | |
126 | svoid answerQuestion(Question question, Concept answer) { |
127 | cdelete(OpenQuestion.class, "question", question); |
128 | uniqueConcept(AnsweredQuestion.class, "question", question, "answer", answer); |
129 | } |
130 | |
131 | svoid answerQuestion(Question question, bool answer) { |
132 | answerQuestion(question, uniqueConcept(answer ? Yes.class : No.class)); |
133 | } |
134 | |
135 | svoid printConcepts { |
136 | print(); |
137 | for (Concept c : allConcepts()) |
138 | printConcept(c); |
139 | } |
140 | |
141 | svoid printConcept(Concept c) { |
142 | print(renderConcept(c)); |
143 | } |
144 | |
145 | static S renderConcept(Concept.Ref ref) { |
146 | ret renderConcept(ref.get()); |
147 | } |
148 | |
149 | static S renderConcept(Concept c) { |
150 | new StringBuilder buf; |
151 | if (c == null) buf.append("null"); |
152 | /*else if (c instanceof ConceptList) { |
153 | for (Concept c2 : ((ConceptList) c).list) |
154 | buf.append(renderConcept(c2) + "\n"); |
155 | }*/ else { |
156 | buf.append(c.id + " " + shortDynamicClassName(c)); |
157 | for (S field : listFields(c)) { |
158 | O val = cget(c, field); |
159 | if (val != null) { |
160 | buf.append(" " + field + "="); |
161 | buf.append(renderConceptShort(val)); |
162 | } |
163 | } |
164 | } |
165 | ret str(buf); |
166 | } |
167 | |
168 | static S renderConceptShort(O val) { |
169 | if (val instanceof Str) |
170 | ret quote(((Str) val).name); |
171 | else if (val instanceof AThing) |
172 | ret "a " + renderConceptShort(((AThing) val).thing.get()); |
173 | else if (val instanceof Concept) |
174 | ret shortDynamicClassName(val) + ((Concept) val).id; |
175 | else |
176 | ret struct(val); |
177 | } |
178 | |
179 | static S renderQuestion(Concept.Ref<Question> q) { |
180 | ret renderQuestion(q.get()); |
181 | } |
182 | |
183 | static S renderQuestion(Question q) { |
184 | ret q.originalText + " (" + shortDynamicClassName(q) + ")"; |
185 | } |
186 | |
187 | svoid printQuestionsAndAnswers { |
188 | L<OpenQuestion> open = list(OpenQuestion.class); |
189 | if (nempty(open)) { |
190 | printAsciiHeading("Open questions"); |
191 | for (OpenQuestion oq : open) |
192 | printIndent(renderQuestion(oq.question)); |
193 | } |
194 | |
195 | L<AnsweredQuestion> answered = list(AnsweredQuestion.class); |
196 | if (nempty(answered)) { |
197 | printAsciiHeading("Answered questions"); |
198 | for (AnsweredQuestion aq : answered) { |
199 | printIndent(2, renderQuestion(aq.question)); |
200 | Concept a = aq.answer.get(); |
201 | if (a instanceof ConceptList) |
202 | for (Concept c2 : ((ConceptList) a).list) |
203 | printIndent(4, renderConcept(c2)); |
204 | else |
205 | printIndent(4, renderConcept(a)); |
206 | } |
207 | } |
208 | } |
209 | |
210 | static bool logic_parse(S s) { |
211 | new Matches m; |
212 | if "the plural of * is *" { |
213 | assertEqic(m.unq(1), plural(m.unq(0))); |
214 | assertEqic(m.unq(0), singular(m.unq(1))); |
215 | true; |
216 | } |
217 | |
218 | if "a * has *" { |
219 | Concept main = aThing(m.unq(0)); |
220 | Concept part = concept(singularFromPlural(m.unq(1))); |
221 | uniqueConcept(HasMulti.class, "main", main, "part", part); |
222 | true; |
223 | } |
224 | |
225 | if "a * has a *" { |
226 | Concept main = aThing(m.unq(0)); |
227 | Concept part = concept(m.unq(1)); |
228 | uniqueConcept(HasA.class, "main", main, "part", part); |
229 | true; |
230 | } |
231 | |
232 | if "the number of * in a * is *" { |
233 | Concept main = aThing(m.unq(1)); |
234 | Concept part = concept(singularFromPlural(m.unq(0))); |
235 | int n = parseInt(m.unq(2)); |
236 | uniqueConcept(MultiCount.class, "main", main, "part", part, "count", n); |
237 | true; |
238 | } |
239 | |
240 | if "let's assume * is a *" || "* is a *" { |
241 | Concept thing = concept(m.unq(0)); |
242 | Concept type = aThing(m.unq(1)); |
243 | uniqueConcept(IsA.class, "thing", thing, "type", type); |
244 | true; |
245 | } |
246 | |
247 | if "how many * are in *" { |
248 | Concept main = concept(m.unq(1)); |
249 | Concept part = concept(singularFromPlural(m.unq(0))); |
250 | uniqueConcept(OpenQuestion.class, "question", |
251 | uniqueConcept(HowManyAreIn.class, "originalText", s, "main", main, "part", part)); |
252 | true; |
253 | } |
254 | |
255 | if "what does * have" { |
256 | Concept thing = concept(m.unq(0)); |
257 | newQ(uniqueConcept(WhatDoesXHave.class, "originalText", s, "thing", thing)); |
258 | true; |
259 | } |
260 | |
261 | if "does * have a *" { |
262 | Concept x = concept(m.unq(0)); |
263 | Concept y = concept(m.unq(1)); |
264 | newQ(uniqueConcept(DoesXHaveAY.class, "originalText", s, "x", x, "y", y)); |
265 | true; |
266 | } |
267 | |
268 | if "* is a synonym of *" { |
269 | mergeStrs(concept(m.unq(0)), concept(m.unq(1))); |
270 | true; |
271 | } |
272 | |
273 | if (trim(s).endsWith("?")) { |
274 | uniqueConcept(OpenQuestion.class, "question", |
275 | uniqueConcept(Question.class, "originalText", s)); |
276 | true; |
277 | } |
278 | |
279 | false; |
280 | } |
281 | |
282 | static void newQ(Question q) { |
283 | uniqueConcept(OpenQuestion.class, "question", q); |
284 | } |
285 | |
286 | static void logic_processRules { |
287 | // Infer statements. |
288 | |
289 | // x is a y && a y has n z => x has n z |
290 | |
291 | for (IsA isA : list(IsA.class)) { |
292 | Concept x = isA.thing.get(), y = isA.type.get(); |
293 | for (MultiCount mc : conceptsWhere(MultiCount.class, "main", y)) |
294 | uniqueConcept(MultiCount.class, "main", x, "part", mc.part, "count", mc.count); // todo: automate the copying |
295 | } |
296 | |
297 | // x is a y && a y has a z => x has a z |
298 | for (IsA isA : list(IsA.class)) { |
299 | Concept x = isA.thing.get(), y = isA.type.get(); |
300 | for (HasA h : conceptsWhere(HasA.class, "main", y)) |
301 | uniqueConcept(HasA.class, "main", x, "part", h.part); |
302 | } |
303 | |
304 | // x has a y => x has "the y of x" |
305 | for (HasA h : list(HasA.class)) |
306 | if (h.main.get() instanceof DefiniteThing) |
307 | uniqueConcept(Has.class, "main", h.main, "part", |
308 | uniqueConcept(TheXOfY.class, "x", h.part, "y", h.main)); |
309 | |
310 | // Answer questions. |
311 | |
312 | for (OpenQuestion oq : list(OpenQuestion.class)) { |
313 | Question _q = oq.question.get(); |
314 | |
315 | if (_q instanceof HowManyAreIn) { |
316 | HowManyAreIn q = cast _q; |
317 | MultiCount mc = conceptWhere(MultiCount.class, "main", q.main, "part", q.part); |
318 | if (mc != null) |
319 | answerQuestion(q, mc); |
320 | } |
321 | |
322 | if (_q instanceof WhatDoesXHave) { |
323 | WhatDoesXHave q = cast _q; |
324 | new ConceptList l; |
325 | l.addAll(conceptsWhere(HasA.class, "main", q.thing)); |
326 | l.addAll(conceptsWhere(Has.class, "main", q.thing)); |
327 | answerQuestion(q, l); |
328 | } |
329 | |
330 | if (_q instanceof DoesXHaveAY) { |
331 | DoesXHaveAY q = cast _q; |
332 | if (hasConcept(HasA.class, "main", q.x, "part", q.y)) |
333 | answerQuestion(q, true); |
334 | } |
335 | } |
336 | } |
337 | |
338 | static Verb verb(S s) { |
339 | ret uniq(Verb, concept(s)); |
340 | } |
Began life as a copy of #1005254
download show line numbers debug dex old transpilations
Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt
No comments. add comment
Snippet ID: | #1005325 |
Snippet name: | Logic 4 [Include, dev.] |
Eternal ID of this version: | #1005325/1 |
Text MD5: | 86e3ecaf16ef8f5f3c6f296cbb6ef11a |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2016-11-06 18:18:05 |
Source code size: | 7974 bytes / 340 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 540 / 761 |
Referenced in: | [show references] |