Download Jar. Libraryless. Click here for Pure Java version (7656L/53K).
1 | !7 |
2 | |
3 | /* |
4 | Event 1 happens before event 2 := |
5 | vars {event 1, event 2, X, Y}
|
6 | Event 1 happens at day X. |
7 | Event 2 happens at day Y. |
8 | X < Y. |
9 | */ |
10 | |
11 | sclass Obj {
|
12 | class Fact implements IStatement {}
|
13 | replace Var with ValuelessVar. |
14 | |
15 | record $HappensBefore$<A, B>(A event1, B event2) extends Fact {}
|
16 | record $HappensAtDay$<A, B>(A event, B y) extends Fact {}
|
17 | record $LessThan$<A, B>(A x, A y) extends Fact {}
|
18 | |
19 | record StatementsWithVars(Set<Var> vars, L<Fact> statements) {
|
20 | *(Fact... statements) {
|
21 | this.statements = asList(statements); |
22 | collectVars(); |
23 | } |
24 | |
25 | void collectVars {
|
26 | vars = new Set; |
27 | fOr (Fact f : statements) |
28 | vars.addAll(print("Vars", findVars(f)));
|
29 | } |
30 | } |
31 | |
32 | L<Var> findVars(O o) { ret ai_findVarObjects Var(o); }
|
33 | |
34 | bool matchIndividual(O a, O b, Map<Var, O> map) {
|
35 | if (a cast Var) |
36 | ret strictPut(map, a, b); |
37 | else |
38 | ret eq(a, b); |
39 | } |
40 | |
41 | Map<Var, O> matchFacts(Fact f1, Fact f2) {
|
42 | if (f1 == null || f2 == null) null; |
43 | if (f1.getClass() != f2.getClass()) null; |
44 | L<Field> fields = nonStaticNonTransientFieldObjects(f1); |
45 | new Map<Var, O> map; |
46 | for (Field f : fields) |
47 | if (!matchIndividual(fieldGet(f, f1), fieldGet(f, f2), map)) |
48 | null; |
49 | ret map; |
50 | } |
51 | |
52 | void recSolve(L<Fact> facts, L<Fact> statements, Map<Var, O> map, IVF1<Map<Var, O>> onSuccess) {
|
53 | if (empty(statements)) {
|
54 | print("No more statements to process");
|
55 | callF(onSuccess, map); |
56 | ret; |
57 | } |
58 | |
59 | Fact f1 = first(statements); |
60 | print("recSolve " + f1);
|
61 | for (Fact f2 : facts) {
|
62 | Map<Var, O> map2 = matchFacts(f1, f2); |
63 | if (map2 != null) {
|
64 | Map<Var, O> map3 = mergeMapsStrictly(map, map2); |
65 | if (map3 == null) continue; // can't merge |
66 | print("Found match for statement: " + map2);
|
67 | print("Full map now: " + map3);
|
68 | recSolve(facts, dropFirst_virtual(statements), map3, onSuccess); |
69 | } |
70 | } |
71 | print("No more matches for: " + f1 + " with " + map);
|
72 | } |
73 | |
74 | // Enrolling happens before graduation. |
75 | // Enrolling happens at day 200. |
76 | // Graduation happens at day 100. // Contradiction! |
77 | |
78 | L<Fact> badFacts = ll( |
79 | new $HappensBefore$("enrolling", "graduation"),
|
80 | new $HappensAtDay$("enrolling", 200),
|
81 | new $HappensAtDay$("graduation", 100)
|
82 | ); |
83 | |
84 | L<Fact> okFacts = ll( |
85 | new $HappensBefore$("enrolling", "graduation"),
|
86 | new $HappensAtDay$("enrolling", 100),
|
87 | new $HappensAtDay$("graduation", 200)
|
88 | ); |
89 | |
90 | StatementsWithVars rule($HappensBefore$ in) {
|
91 | O event1 = in.event1, event2 = in.event2; |
92 | Var X = new Var("X"), Y = new Var("Y");
|
93 | ret print(new StatementsWithVars( |
94 | new $HappensAtDay$(event1, X), |
95 | new $HappensAtDay$(event2, Y), |
96 | new $LessThan$(X, Y) |
97 | )); |
98 | } |
99 | |
100 | StatementsWithVars trueFalse(bool b) {
|
101 | ret b ? new StatementsWithVars : null; |
102 | } |
103 | |
104 | StatementsWithVars rule($LessThan$ in) {
|
105 | print("Checking " + in);
|
106 | O x = in.x, y = in.y; |
107 | if (x instanceof Number && y instanceof Number) |
108 | ret trueFalse(print(in + " => ", cmp(x/Number, y/Number) < 0)); |
109 | null; |
110 | } |
111 | |
112 | *() {
|
113 | pnlWithHeading("Bad facts", badFacts);
|
114 | checkFacts(badFacts); |
115 | pnlWithHeading("OK facts", okFacts);
|
116 | checkFacts(okFacts); |
117 | } |
118 | |
119 | void checkFacts(L<Fact> _facts) {
|
120 | for (Fact f : _facts) {
|
121 | StatementsWithVars out = cast callOpt(this, 'rule, f); |
122 | if (out == null) continue; |
123 | // Now we have a bunch of statements with possible variables. |
124 | // Let's match them with the facts. |
125 | recSolve(_facts, out.statements, null, map -> { print("Got: " + map); });
|
126 | } |
127 | } |
128 | } |
129 | |
130 | p-exp { new Obj; } |
download show line numbers debug dex old transpilations
Travelled to 7 computer(s): bhatertpkbcr, mqqgnosmbjvj, omdjrrnzbjjv, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt
No comments. add comment
| Snippet ID: | #1025408 |
| Snippet name: | Rule Transpilation Spike [dev.] |
| Eternal ID of this version: | #1025408/35 |
| Text MD5: | 49f18a8678974da8993e38975c45d3db |
| Transpilation MD5: | 48c1aeb4f11cc41130884352af640489 |
| Author: | stefan |
| Category: | javax / a.i. |
| Type: | JavaX source code (desktop) |
| Public (visible to everyone): | Yes |
| Archived (hidden from active list): | No |
| Created/modified: | 2019-09-28 21:36:23 |
| Source code size: | 3770 bytes / 130 lines |
| Pitched / IR pitched: | No / No |
| Views / Downloads: | 642 / 1996 |
| Version history: | 34 change(s) |
| Referenced in: | [show references] |