@@ -13,6 +13,22 @@ namespace AngouriMath
1313{
1414 partial record Entity
1515 {
16+ /// <summary>
17+ /// Whether this node, its children aside, has a compiled form: false by default, as
18+ /// <see cref="CompileNode"/>'s default is to throw, and true beside every override that
19+ /// compiles rather than throws.
20+ /// </summary>
21+ private protected virtual bool CompilesItself => false ;
22+
23+ /// <summary>
24+ /// Whether the compiler has a form for every node of this expression, so that a caller
25+ /// that would fall back rather than fail can ask first instead of catching
26+ /// <see cref="UncompilableNodeException"/>. The variables are not checked against a
27+ /// list: which ones an expression is compiled over is the caller's to say.
28+ /// https://github.com/asc-community/AngouriMath/issues/1603
29+ /// </summary>
30+ internal bool HasCompiledForm => CompilesItself && DirectChildren . All ( child => child . HasCompiledForm ) ;
31+
1632 private protected virtual void CompileNode ( Compiler compiler )
1733 => throw new UncompilableNodeException (
1834 $ "`{ Stringize ( ) } `, a node of type { GetType ( ) } , does not support compilation. "
@@ -38,12 +54,16 @@ internal void InnerCompile(Compiler compiler)
3854
3955 public partial record Number
4056 {
57+ private protected override bool CompilesItself => true ;
58+
4159 private protected override void CompileNode ( Compiler compiler ) =>
4260 compiler . Instructions . Add ( new ( InstructionType . PUSH_CONST , Value : ( ( Complex ) this ) . ToNumerics ( ) ) ) ;
4361 }
4462
4563 public partial record Variable
4664 {
65+ private protected override bool CompilesItself => true ;
66+
4767 private protected override void CompileNode ( Compiler compiler ) =>
4868 compiler . Instructions . Add ( new ( InstructionType . PUSH_VAR ,
4969 compiler . VarNamespace . TryGetValue ( this , out var slot )
@@ -65,6 +85,8 @@ public override int GetHashCode()
6585
6686 public partial record Constant
6787 {
88+ private protected override bool CompilesItself => true ;
89+
6890 // A constant is its value. The named ones are substituted by value before
6991 // compiling; the base of ln and exp is Euler's number standing in the operator's
7092 // definition, which substitution leaves alone (#994), so it arrives here.
@@ -82,6 +104,8 @@ private protected override void CompileNode(Compiler compiler) =>
82104 // Note: We pop values when executing instructions, so we add instructions in reverse child order
83105 public partial record Sumf
84106 {
107+ private protected override bool CompilesItself => true ;
108+
85109 private protected override void CompileNode ( Compiler compiler )
86110 {
87111 Addend . InnerCompile ( compiler ) ;
@@ -92,6 +116,8 @@ private protected override void CompileNode(Compiler compiler)
92116
93117 public partial record Minusf
94118 {
119+ private protected override bool CompilesItself => true ;
120+
95121 private protected override void CompileNode ( Compiler compiler )
96122 {
97123 Subtrahend . InnerCompile ( compiler ) ;
@@ -102,6 +128,8 @@ private protected override void CompileNode(Compiler compiler)
102128
103129 public partial record Mulf
104130 {
131+ private protected override bool CompilesItself => true ;
132+
105133 private protected override void CompileNode ( Compiler compiler )
106134 {
107135 Multiplicand . InnerCompile ( compiler ) ;
@@ -112,6 +140,8 @@ private protected override void CompileNode(Compiler compiler)
112140
113141 public partial record Divf
114142 {
143+ private protected override bool CompilesItself => true ;
144+
115145 private protected override void CompileNode ( Compiler compiler )
116146 {
117147 Divisor . InnerCompile ( compiler ) ;
@@ -122,6 +152,8 @@ private protected override void CompileNode(Compiler compiler)
122152
123153 public partial record Modf
124154 {
155+ private protected override bool CompilesItself => true ;
156+
125157 private protected override void CompileNode ( Compiler compiler )
126158 {
127159 Divisor . InnerCompile ( compiler ) ;
@@ -132,6 +164,8 @@ private protected override void CompileNode(Compiler compiler)
132164
133165 public partial record Powf
134166 {
167+ private protected override bool CompilesItself => true ;
168+
135169 private protected override void CompileNode ( Compiler compiler )
136170 {
137171 Exponent . InnerCompile ( compiler ) ;
@@ -142,6 +176,8 @@ private protected override void CompileNode(Compiler compiler)
142176
143177 public partial record Sinf
144178 {
179+ private protected override bool CompilesItself => true ;
180+
145181 private protected override void CompileNode ( Compiler compiler )
146182 {
147183 Argument . InnerCompile ( compiler ) ;
@@ -151,6 +187,8 @@ private protected override void CompileNode(Compiler compiler)
151187
152188 public partial record Cosf
153189 {
190+ private protected override bool CompilesItself => true ;
191+
154192 private protected override void CompileNode ( Compiler compiler )
155193 {
156194 Argument . InnerCompile ( compiler ) ;
@@ -160,6 +198,8 @@ private protected override void CompileNode(Compiler compiler)
160198
161199 public partial record Secantf
162200 {
201+ private protected override bool CompilesItself => true ;
202+
163203 private protected override void CompileNode ( Compiler compiler )
164204 {
165205 Argument . InnerCompile ( compiler ) ;
@@ -169,6 +209,8 @@ private protected override void CompileNode(Compiler compiler)
169209
170210 public partial record Cosecantf
171211 {
212+ private protected override bool CompilesItself => true ;
213+
172214 private protected override void CompileNode ( Compiler compiler )
173215 {
174216 Argument . InnerCompile ( compiler ) ;
@@ -178,6 +220,8 @@ private protected override void CompileNode(Compiler compiler)
178220
179221 public partial record Tanf
180222 {
223+ private protected override bool CompilesItself => true ;
224+
181225 private protected override void CompileNode ( Compiler compiler )
182226 {
183227 Argument . InnerCompile ( compiler ) ;
@@ -187,6 +231,8 @@ private protected override void CompileNode(Compiler compiler)
187231
188232 public partial record Cotanf
189233 {
234+ private protected override bool CompilesItself => true ;
235+
190236 private protected override void CompileNode ( Compiler compiler )
191237 {
192238 Argument . InnerCompile ( compiler ) ;
@@ -196,6 +242,8 @@ private protected override void CompileNode(Compiler compiler)
196242
197243 public partial record Logf
198244 {
245+ private protected override bool CompilesItself => true ;
246+
199247 private protected override void CompileNode ( Compiler compiler )
200248 {
201249 // Unlike AngouriMath which accepts Base as the first parameter,
@@ -209,6 +257,8 @@ private protected override void CompileNode(Compiler compiler)
209257
210258 public partial record Arcsinf
211259 {
260+ private protected override bool CompilesItself => true ;
261+
212262 private protected override void CompileNode ( Compiler compiler )
213263 {
214264 Argument . InnerCompile ( compiler ) ;
@@ -218,6 +268,8 @@ private protected override void CompileNode(Compiler compiler)
218268
219269 public partial record Arccosf
220270 {
271+ private protected override bool CompilesItself => true ;
272+
221273 private protected override void CompileNode ( Compiler compiler )
222274 {
223275 Argument . InnerCompile ( compiler ) ;
@@ -227,6 +279,8 @@ private protected override void CompileNode(Compiler compiler)
227279
228280 public partial record Arctanf
229281 {
282+ private protected override bool CompilesItself => true ;
283+
230284 private protected override void CompileNode ( Compiler compiler )
231285 {
232286 Argument . InnerCompile ( compiler ) ;
@@ -236,6 +290,8 @@ private protected override void CompileNode(Compiler compiler)
236290
237291 public partial record Arccotanf
238292 {
293+ private protected override bool CompilesItself => true ;
294+
239295 private protected override void CompileNode ( Compiler compiler )
240296 {
241297 Argument . InnerCompile ( compiler ) ;
@@ -245,6 +301,8 @@ private protected override void CompileNode(Compiler compiler)
245301
246302 public partial record Arcsecantf
247303 {
304+ private protected override bool CompilesItself => true ;
305+
248306 private protected override void CompileNode ( Compiler compiler )
249307 {
250308 Argument . InnerCompile ( compiler ) ;
@@ -254,6 +312,8 @@ private protected override void CompileNode(Compiler compiler)
254312
255313 public partial record Arccosecantf
256314 {
315+ private protected override bool CompilesItself => true ;
316+
257317 private protected override void CompileNode ( Compiler compiler )
258318 {
259319 Argument . InnerCompile ( compiler ) ;
@@ -263,6 +323,8 @@ private protected override void CompileNode(Compiler compiler)
263323
264324 public partial record Factorialf
265325 {
326+ private protected override bool CompilesItself => true ;
327+
266328 private protected override void CompileNode ( Compiler compiler )
267329 {
268330 Argument . InnerCompile ( compiler ) ;
@@ -288,8 +350,70 @@ private protected override void CompileNode(Compiler compiler) =>
288350 throw new UncompilableNodeException ( $ "A limit cannot be compiled: `{ Stringize ( ) } `") ;
289351 }
290352
353+ // The floors, the rounding and the extremes, which the solver's numerical search needs
354+ // compiled to run on `floor(x) = x/2 + 1/3` or `max(x, 1) = 2 x` at all.
355+ // https://github.com/asc-community/AngouriMath/issues/1603
356+ public partial record Floorf
357+ {
358+ private protected override bool CompilesItself => true ;
359+
360+ private protected override void CompileNode ( Compiler compiler )
361+ {
362+ Argument . InnerCompile ( compiler ) ;
363+ compiler . Instructions . Add ( new ( InstructionType . CALL_FLOOR ) ) ;
364+ }
365+ }
366+
367+ public partial record Ceilf
368+ {
369+ private protected override bool CompilesItself => true ;
370+
371+ private protected override void CompileNode ( Compiler compiler )
372+ {
373+ Argument . InnerCompile ( compiler ) ;
374+ compiler . Instructions . Add ( new ( InstructionType . CALL_CEIL ) ) ;
375+ }
376+ }
377+
378+ public partial record Roundf
379+ {
380+ private protected override bool CompilesItself => true ;
381+
382+ private protected override void CompileNode ( Compiler compiler )
383+ {
384+ Argument . InnerCompile ( compiler ) ;
385+ compiler . Instructions . Add ( new ( InstructionType . CALL_ROUND ) ) ;
386+ }
387+ }
388+
389+ public partial record Maxf
390+ {
391+ private protected override bool CompilesItself => true ;
392+
393+ private protected override void CompileNode ( Compiler compiler )
394+ {
395+ Right . InnerCompile ( compiler ) ;
396+ Left . InnerCompile ( compiler ) ;
397+ compiler . Instructions . Add ( new ( InstructionType . CALL_MAX ) ) ;
398+ }
399+ }
400+
401+ public partial record Minf
402+ {
403+ private protected override bool CompilesItself => true ;
404+
405+ private protected override void CompileNode ( Compiler compiler )
406+ {
407+ Right . InnerCompile ( compiler ) ;
408+ Left . InnerCompile ( compiler ) ;
409+ compiler . Instructions . Add ( new ( InstructionType . CALL_MIN ) ) ;
410+ }
411+ }
412+
291413 public partial record Signumf
292414 {
415+ private protected override bool CompilesItself => true ;
416+
293417 private protected override void CompileNode ( Compiler compiler )
294418 {
295419 Argument . InnerCompile ( compiler ) ;
@@ -299,6 +423,8 @@ private protected override void CompileNode(Compiler compiler)
299423
300424 public partial record Absf
301425 {
426+ private protected override bool CompilesItself => true ;
427+
302428 private protected override void CompileNode ( Compiler compiler )
303429 {
304430 Argument . InnerCompile ( compiler ) ;
@@ -308,6 +434,8 @@ private protected override void CompileNode(Compiler compiler)
308434
309435 public partial record Phif
310436 {
437+ private protected override bool CompilesItself => true ;
438+
311439 private protected override void CompileNode ( Compiler compiler )
312440 {
313441 Argument . InnerCompile ( compiler ) ;
0 commit comments