Libraryless. Click here for Pure Java version (5915L/38K).
1 | // Now probabilistic - i.e. |
2 | // transformers can return WithProbability or call lowerProbability(). |
3 | // B is the type of object we handle. |
4 | // Hopefully this class is persistent? |
5 | sclass TransformersOnObjects<B> implements Steppable { |
6 | replace Trail with O. |
7 | |
8 | // using the oldschool type F1 here because it's a bit easier to handle |
9 | new AllOnAll_probabilistic<F1, B> allOnAll; |
10 | new Set<B> bs; |
11 | new MultiSetMap<B, Trail> trails; |
12 | new Map<O, IF2> backTransformers; // reverse of each transformer |
13 | new Map<O, Double> probabilities; |
14 | |
15 | bool verboseAddObject = true; |
16 | transient new ThreadLocal<Double> currentProbability; |
17 | |
18 | srecord TransformationTrail(O transformer, O argument) { |
19 | F1 backTransformer; // really complex back transformer |
20 | toString { ret squareBracket(str(transformer)) + " on " + squareBracket(str(argument)); } |
21 | } |
22 | |
23 | // If this is true and a transformer returns an Iterable, |
24 | // we unpack it and discard the Iterable. |
25 | bool autoUnpackIterables = true; |
26 | |
27 | // make a trail for each transformer application |
28 | bool autoTrails = true; |
29 | |
30 | // keep multiple trails per object |
31 | bool allowMultipleTrails = true; |
32 | |
33 | // when calling think() |
34 | long maxSteps = 1000; |
35 | |
36 | AllOnAllOperation<F1, B> op = new(allOnAll, new TheOp); |
37 | |
38 | // make it a class so it's persistable |
39 | class TheOp implements IVF2<F1, B> { |
40 | public void get(F1 a, B b) { |
41 | if (!functionCallableOn_nonSynthetic(a, b)) ret; |
42 | temp tempSetTL(currentProbability, getProbability(a)*getProbability(b)); |
43 | O out = callFOpt(a, b); |
44 | O trail = autoTrails ? makeTrailForTransformerApplication(a, b) : null; |
45 | if (out == null) ret; |
46 | if (out instanceof WithProbability) { |
47 | lowerCurrentProbability(((WithProbability) out).probability); |
48 | out = ((WithProbability) out)!; |
49 | if (out == null) ret; |
50 | } |
51 | if (autoUnpackIterables && out instanceof Iterable) // don't use this anymore |
52 | for (O x : (Iterable) out) addObject((B) x, trail); |
53 | else |
54 | addObject((B) out, trail); |
55 | } |
56 | } |
57 | |
58 | class ProbFunc implements IF2<F1, B, Double> { |
59 | public Double get(F1 a, B b) { |
60 | ret getProbability(a) * getProbability(b); |
61 | } |
62 | } |
63 | |
64 | *() { |
65 | allOnAll.probabilityForPair = new ProbFunc; |
66 | } |
67 | |
68 | bool addAll(Iterable<B> l) { |
69 | bool change; |
70 | fOr (B b : l) if (add(b)) set change; |
71 | ret change; |
72 | } |
73 | |
74 | bool add(B b) { ret addObject(b); } |
75 | |
76 | bool addObject(B b) { |
77 | if (!addIfNotNull(bs, b)) false; |
78 | double prob = or(currentProbability!, 1.0); |
79 | setProbability(b, prob); |
80 | if (verboseAddObject) print(prob == 1 |
81 | ? "Added: " + sfu(b) |
82 | : "Added with " + WithProbability(prob, sfu(b))); |
83 | allOnAll.addB(b); |
84 | true; |
85 | } |
86 | |
87 | void addObject(B b, O trail) { |
88 | if (b == null) ret; |
89 | add(b); |
90 | if (trail != null && (allowMultipleTrails || !trails.containsKey(b))) |
91 | trails.put(b, trail); |
92 | } |
93 | |
94 | void addTransformer(F1 f) { |
95 | allOnAll.addA(f); |
96 | } |
97 | |
98 | // simple backtransformer only taking the transformed object |
99 | void addTransformer(F1 f, F1 backTransformer) { |
100 | addTransformer(f, backTransformer == null ? null |
101 | : new SimplifiedBackTransformer(backTransformer)); |
102 | } |
103 | |
104 | srecord SimplifiedBackTransformer(F1 backTransformer) implements IF2 { |
105 | public O get(O in, O out) { ret callFIfActuallyCallable(backTransformer, out); } |
106 | toString { ret str(backTransformer); } |
107 | } |
108 | |
109 | // complex backtransformer taking the original and the transformed object |
110 | <A, C> void addTransformer(F1<A, C> f, IF2<A, C, O> backTransformer) { |
111 | addTransformer(f); |
112 | mapPut(backTransformers, f, backTransformer); |
113 | } |
114 | |
115 | void addTransformer(VF2 f) { |
116 | addTransformer(func(O a) { |
117 | addTransformer(func(O b) { |
118 | if (callableOn_nonSynthetic(f, "get", a, b)) |
119 | f.get(a, b); |
120 | null; |
121 | }); |
122 | null; |
123 | }); |
124 | } |
125 | |
126 | void addTransformer(F2 f) { |
127 | addTransformer(func(O a) { |
128 | addTransformer(func(O b) { |
129 | callableOn_nonSynthetic(f, "get", a, b) ? f.get(a, b) : null |
130 | }); |
131 | null; |
132 | }); |
133 | } |
134 | |
135 | public bool step() { ret op.step(); } |
136 | |
137 | L<B> getObjects() { ret allOnAll.getBs(); } |
138 | |
139 | O makeTrailForTransformerApplication(O transformer, B argument) { |
140 | ret new TransformationTrail(transformer, argument); |
141 | } |
142 | |
143 | void printWithTrails() { |
144 | pnlMap(getObjects(), b -> { |
145 | Set _trails = trails.get(b); |
146 | ret sfu(b) + (empty(_trails) ? "" |
147 | : " [" + nTrails(_trails) + ": " + joinWithComma(_trails) + "]"); |
148 | }); |
149 | } |
150 | |
151 | // only returns the actual TransformationTrails |
152 | Cl<TransformationTrail> getTrails(B b) { |
153 | ret instancesOf TransformationTrail(trails.get(b)); |
154 | } |
155 | |
156 | Cl<TransformationTrail> getTrailsBy(B b, O transformer) { |
157 | ret filter(getTrails(b), t -> eq(((TransformationTrail) t).transformer, transformer)); |
158 | } |
159 | |
160 | TransformationTrail getTrailBy(B b, O transformer) { |
161 | ret firstThat(getTrails(b), t -> eq(((TransformationTrail) t).transformer, transformer)); |
162 | } |
163 | |
164 | IF2 getBackTransformer(O transformer) { |
165 | ret backTransformers.get(transformer); |
166 | } |
167 | |
168 | void printTransformers() { |
169 | pnl(allOnAll.getAs()); |
170 | } |
171 | |
172 | double getProbability(O o) { |
173 | ret or(probabilities.get(o), 1.0); |
174 | } |
175 | |
176 | // Note: works only for transformers that are not rewritten by the addTransformer method |
177 | // Works for all objects |
178 | <A> A setProbability(A o, double p) { |
179 | if (o == null) null; |
180 | Double pOld = probabilities.get(p); |
181 | if (pOld != null) { |
182 | if (p == 1.0) |
183 | probabilities.remove(o); |
184 | else if (pOld.doubleValue() != p) |
185 | probabilities.put(o, p); |
186 | } else if (p != 1.0) |
187 | probabilities.put(o, p); |
188 | ret o; |
189 | } |
190 | |
191 | // p = 0.0 to 1.0 |
192 | void lowerProbability(double p) { lowerCurrentProbability(p); } |
193 | void lowerCurrentProbability(double p) { |
194 | currentProbability.set(currentProbability! * p); |
195 | } |
196 | |
197 | void think { stepAllWithStats(this, maxSteps); } |
198 | } |
download show line numbers debug dex old transpilations
Travelled to 7 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tvejysmllsmz, vouqrxazstgt, xrpafgyirdlv
No comments. add comment
Snippet ID: | #1028385 |
Snippet name: | TransformersOnObjects |
Eternal ID of this version: | #1028385/83 |
Text MD5: | 26083c47707dd46a8804c4ffbfbfdb38 |
Transpilation MD5: | daa40fc33baba3e68bb9d2cf5a8d6842 |
Author: | stefan |
Category: | javax |
Type: | JavaX fragment (include) |
Public (visible to everyone): | Yes |
Archived (hidden from active list): | No |
Created/modified: | 2020-07-12 12:46:00 |
Source code size: | 6062 bytes / 198 lines |
Pitched / IR pitched: | No / No |
Views / Downloads: | 539 / 1139 |
Version history: | 82 change(s) |
Referenced in: | [show references] |