eyeling 1.15.3 → 1.15.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/HANDBOOK.md CHANGED
@@ -561,6 +561,47 @@ Implementation notes:
561
561
  - Keys are _structural_. Atoms use stable IDs; lists use element keys; variables use their identity (so two different variables are **not** conflated). This keeps the cycle check conservative and avoids accidental pruning.
562
562
  - This is not full tabling: it does not memoize answers, it only guards against immediate cycles (the common “A depends on A” loops).
563
563
 
564
+ ### 8.4.1 Minimal completed-goal tabling
565
+
566
+ Eyeling has a **very small, deliberately conservative answer table** for backward goals.
567
+
568
+ What is cached:
569
+
570
+ - only **completed** answer sets
571
+ - keyed by the **fully substituted goal list**
572
+ - only when the proof is entered from a “top-level” call shape (no active per-branch `visited` context)
573
+ - only when the engine is not in a result-limiting mode such as `maxResults`
574
+
575
+ What is **not** cached:
576
+
577
+ - pending / in-progress goals
578
+ - recursive dependency states
579
+ - partial answer streams
580
+ - branch-local states inside an active recursive proof
581
+
582
+ This matters because exposing **pending** answers without dependency propagation would change the meaning of recursive programs. Eyeling therefore caches only results that are already complete and replays them only when the surrounding proof context is equivalent.
583
+
584
+ The cache is invalidated whenever any of the following changes:
585
+
586
+ - the number of known facts
587
+ - the number of backward rules
588
+ - the scoped-closure level
589
+ - whether a frozen scoped snapshot is active
590
+
591
+ So this is **not SLG tabling** and not a general recursion engine. It is best understood as a reuse optimization for repeated backward proofs in a stable proof environment.
592
+
593
+ Typical win cases:
594
+
595
+ - many repeated `log:query` directives with the **same premise**
596
+ - repeated forward-rule body proofs that ask the same completed backward question
597
+ - “query-like” workloads where the expensive part is a repeated backward proof and the fact store does not change between calls
598
+
599
+ Typical non-win cases:
600
+
601
+ - first-time proofs
602
+ - recursive subgoals whose value depends on future answers
603
+ - workloads where the fact set changes between almost every call
604
+
564
605
  ### 8.5 Backward rules: indexed by head predicate
565
606
 
566
607
  Backward rules are indexed in `backRules.__byHeadPred`. When proving a goal with IRI predicate `p`, Eyeling retrieves:
@@ -706,7 +747,7 @@ Forward chaining runs inside an _outer loop_ that alternates:
706
747
 
707
748
  This produces deterministic behavior for scoped operations: they observe a stable snapshot, not a moving target.
708
749
 
709
- **Implementation note (performance):** the two-phase scheme is only needed when the program actually uses scoped built-ins. If no rule contains `log:collectAllIn`, `log:forAllIn`, `log:includes`, or `log:notIncludes`, Eyeling now **skips Phase B entirely** and runs only a single saturation. This avoids re-running the forward fixpoint and can prevent a “query-like” forward rule (one whose body contains an expensive backward proof search) from being executed twice.
750
+ **Implementation note (performance):** the two-phase scheme is only needed when the program actually uses scoped built-ins. If no rule contains `log:collectAllIn`, `log:forAllIn`, `log:includes`, or `log:notIncludes`, Eyeling **skips Phase B entirely** and runs only a single saturation. This avoids re-running the forward fixpoint and can prevent a “query-like” forward rule (one whose body contains an expensive backward proof search) from being executed twice.
710
751
 
711
752
  **Implementation note (performance):** in Phase A there is no snapshot, so scoped built-ins (and priority-gated scoped queries) are guaranteed to “delay” by failing.
712
753
  Instead of proving the entire forward-rule body only to fail at the end, Eyeling precomputes whether a forward rule depends on scoped built-ins and skips it until a snapshot exists and the requested closure level is reached. This can avoid very expensive proof searches in programs that combine recursion with `log:*In` built-ins.
@@ -1379,6 +1420,8 @@ Each enumerated rule is standardized apart (fresh variable names) before unifica
1379
1420
 
1380
1421
  This is “forward-rule-like” in spirit (premise ⇒ conclusion), but the instantiated conclusion triples are **not added back into the fact store**; they are just what Eyeling prints.
1381
1422
 
1423
+ **Implementation note (performance):** repeated top-level `log:query` directives with the **same premise formula** are a good fit for Eyeling’s minimal completed-goal tabling (§8.4.1). The first query still performs the full backward proof; later identical premises can reuse the completed answer set as long as the saturated closure and scoped-query context are unchanged.
1424
+
1382
1425
  **Important details:**
1383
1426
 
1384
1427
  - Only **top-level** `{...} log:query {...}.` directives are recognized. Inside quoted formulas (or inside rule bodies/heads) it is just an ordinary triple.
@@ -2448,7 +2491,7 @@ It runs against the external suite.
2448
2491
 
2449
2492
  That means:
2450
2493
 
2451
- - the benchmark is shared
2494
+ - the compliance test suite is shared
2452
2495
  - the contract is public
2453
2496
  - the result is independently meaningful
2454
2497
 
@@ -0,0 +1,193 @@
1
+ # ====================================================================================
2
+ # Floating-point-first EMA tracking envelope
3
+ #
4
+ # Why this example exists:
5
+ # It is another floating-point-first certificate in the same family as the servo,
6
+ # RC-discharge, and thermal-cooling examples, but now phrased as an exponential
7
+ # moving average (EMA) tracker.
8
+ #
9
+ # Physical story:
10
+ # Let e(k) be the absolute tracking error of an EMA estimator relative to a constant
11
+ # target. Then
12
+ #
13
+ # e(k+1) = a * e(k)
14
+ #
15
+ # where a is the complement of the EMA gain. In this example we choose
16
+ #
17
+ # a = exp(-Ts/tau) = exp(-1/6)
18
+ #
19
+ # with Ts = 0.5 s and tau = 3 s.
20
+ #
21
+ # Since exp(-1/6) is transcendental, we certify it by a double interval:
22
+ #
23
+ # 8.464817248e-1 <= exp(-1/6) <= 8.464817249e-1
24
+ #
25
+ # and propagate a floating-point envelope for the tracking error.
26
+ #
27
+ # What is certified:
28
+ # * the double interval is nonempty and strictly below 1
29
+ # * the tracking-error envelope shrinks at every sample
30
+ # * from an initial error of 8.0e0, the estimator is guaranteed within 2.5e-1
31
+ # by sample 21
32
+ # * with Ts = 5.0e-1 s, that means guaranteed settling by 1.05e1 s
33
+ # ====================================================================================
34
+
35
+ @prefix : <http://example.org/floating-ema#>.
36
+ @prefix math: <http://www.w3.org/2000/10/swap/math#>.
37
+ @prefix log: <http://www.w3.org/2000/10/swap/log#>.
38
+
39
+ # ----------
40
+ # Parameters
41
+ # ----------
42
+
43
+ :ema a :SampledEMAEnvelope;
44
+ :samplePeriod 5.0e-1;
45
+ :timeConstant 3.0e0;
46
+ :exactDecaySymbol "exp(-1/6)";
47
+ :decayLower 8.464817248e-1;
48
+ :decayUpper 8.464817249e-1;
49
+ :initialAbsTrackingError 8.0e0;
50
+ :tolerance 2.5e-1;
51
+ :maxStep 24.
52
+
53
+ # ----------------------------------------------------------------
54
+ # The double interval is a finite certificate for a transcendental
55
+ # ----------------------------------------------------------------
56
+
57
+ {
58
+ :ema :decayLower ?lo.
59
+ :ema :decayUpper ?hi.
60
+ ?lo math:lessThan ?hi.
61
+ ?hi math:lessThan 1.0e0.
62
+ ?lo math:greaterThan 0.0e0.
63
+ }
64
+ =>
65
+ {
66
+ :ema :decayCertificate :CertifiedDoubleInterval.
67
+ :ema :contractiveDecay true.
68
+ }.
69
+
70
+ # ----------------
71
+ # Initial envelope
72
+ # ----------------
73
+
74
+ {
75
+ :ema :initialAbsTrackingError ?e0.
76
+ }
77
+ =>
78
+ {
79
+ :ema :trackingErrorEnvelopeAt (0 ?e0 ?e0).
80
+ }.
81
+
82
+ # -------------------------------------
83
+ # Envelope propagation
84
+ # lower(k+1) = decayLower * lower(k)
85
+ # upper(k+1) = decayUpper * upper(k)
86
+ # -------------------------------------
87
+
88
+ {
89
+ :ema :maxStep ?max;
90
+ :decayLower ?aLo;
91
+ :decayUpper ?aHi.
92
+ :ema :trackingErrorEnvelopeAt (?k ?lo ?hi).
93
+ ?k math:lessThan ?max.
94
+ ( ?k 1 ) math:sum ?k1.
95
+ ( ?aLo ?lo ) math:product ?lo1.
96
+ ( ?aHi ?hi ) math:product ?hi1.
97
+ }
98
+ =>
99
+ {
100
+ :ema :trackingErrorEnvelopeAt (?k1 ?lo1 ?hi1).
101
+ }.
102
+
103
+ # -----------------------------
104
+ # The envelope shrinks strictly
105
+ # -----------------------------
106
+
107
+ {
108
+ :ema :trackingErrorEnvelopeAt (?k ?lo ?hi).
109
+ ( ?k 1 ) math:sum ?k1.
110
+ :ema :trackingErrorEnvelopeAt (?k1 ?lo1 ?hi1).
111
+ ?hi1 math:lessThan ?hi.
112
+ }
113
+ =>
114
+ {
115
+ :ema :strictContractionAt ?k.
116
+ }.
117
+
118
+ # --------------------------------
119
+ # Settlement in the tolerance band
120
+ # --------------------------------
121
+
122
+ {
123
+ :ema :trackingErrorEnvelopeAt (?k ?lo ?hi).
124
+ :ema :tolerance ?tol.
125
+ ?hi math:lessThan ?tol.
126
+ }
127
+ =>
128
+ {
129
+ :ema :settledCandidate ?k.
130
+ }.
131
+
132
+ {
133
+ :ema :settledCandidate ?k.
134
+ ?k math:greaterThan 0.
135
+ ( ?k 1 ) math:difference ?km1.
136
+ :ema :trackingErrorEnvelopeAt (?km1 ?prevLo ?prevHi).
137
+ :ema :tolerance ?tol.
138
+ ?prevHi math:notLessThan ?tol.
139
+ }
140
+ =>
141
+ {
142
+ :ema :firstSettledStep ?k.
143
+ }.
144
+
145
+ {
146
+ :ema :firstSettledStep ?k.
147
+ :ema :samplePeriod ?ts.
148
+ ( ?k ?ts ) math:product ?t.
149
+ }
150
+ =>
151
+ {
152
+ :ema :firstSettledTime ?t.
153
+ }.
154
+
155
+ # -----------------------------------------------------------
156
+ # Readable engineering summary for the floating-point witness
157
+ # -----------------------------------------------------------
158
+
159
+ {
160
+ :ema :firstSettledStep ?k;
161
+ :firstSettledTime ?t;
162
+ :tolerance ?tol;
163
+ :exactDecaySymbol ?sym;
164
+ :decayLower ?aLo;
165
+ :decayUpper ?aHi.
166
+ }
167
+ log:query
168
+ {
169
+ :result :summary (
170
+ "exact-decay" ?sym
171
+ "double-lower" ?aLo
172
+ "double-upper" ?aHi
173
+ "tolerance" ?tol
174
+ "first-settled-step" ?k
175
+ "first-settled-time-s" ?t
176
+ ).
177
+ }.
178
+
179
+ {
180
+ :ema :trackingErrorEnvelopeAt (?k ?lo ?hi).
181
+ }
182
+ log:query
183
+ {
184
+ :result :envelope (?k ?lo ?hi).
185
+ }.
186
+
187
+ {
188
+ :ema :strictContractionAt ?k.
189
+ }
190
+ log:query
191
+ {
192
+ :result :contractionAt ?k.
193
+ }.
@@ -0,0 +1,190 @@
1
+ # =======================================================================================
2
+ # Floating-point-first RC discharge envelope
3
+ #
4
+ # Why this example exists:
5
+ # It is another floating-point-first certificate, parallel to the servo-envelope style,
6
+ # but framed as a passive RC discharge.
7
+ #
8
+ # Physical story:
9
+ # A sampled RC voltage obeys
10
+ #
11
+ # v(k+1) = a * v(k)
12
+ #
13
+ # with exact discrete decay factor
14
+ #
15
+ # a = exp(-Ts/tau) = exp(-1/4)
16
+ #
17
+ # for Ts = 25 ms and tau = 100 ms.
18
+ #
19
+ # Because exp(-1/4) is transcendental, we certify it by a double interval:
20
+ #
21
+ # 7.788007830e-1 <= exp(-1/4) <= 7.788007831e-1
22
+ #
23
+ # and propagate a floating-point envelope on the capacitor voltage.
24
+ #
25
+ # What is certified:
26
+ # * the double interval is nonempty and strictly below 1
27
+ # * the voltage envelope shrinks sample by sample
28
+ # * from an initial voltage of 2.40e1 V, the capacitor is guaranteed below 1.0e0 V
29
+ # by sample 15
30
+ # * with Ts = 2.5e-2 s, that means guaranteed settling by 3.75e-1 s
31
+ # =======================================================================================
32
+
33
+ @prefix : <http://example.org/floating-rc#>.
34
+ @prefix math: <http://www.w3.org/2000/10/swap/math#>.
35
+ @prefix log: <http://www.w3.org/2000/10/swap/log#>.
36
+
37
+ # ----------
38
+ # Parameters
39
+ # ----------
40
+
41
+ :rc a :SampledRCEnvelope;
42
+ :samplePeriod 2.5e-2;
43
+ :timeConstant 1.0e-1;
44
+ :exactDecaySymbol "exp(-1/4)";
45
+ :decayLower 7.788007830e-1;
46
+ :decayUpper 7.788007831e-1;
47
+ :initialVoltage 2.40e1;
48
+ :tolerance 1.0e0;
49
+ :maxStep 18.
50
+
51
+ # ----------------------------------------------------------------
52
+ # The double interval is a finite certificate for a transcendental
53
+ # ----------------------------------------------------------------
54
+
55
+ {
56
+ :rc :decayLower ?lo; :decayUpper ?hi.
57
+ ?lo math:lessThan ?hi.
58
+ ?hi math:lessThan 1.0e0.
59
+ ?lo math:greaterThan 0.0e0.
60
+ }
61
+ =>
62
+ {
63
+ :rc :decayCertificate :CertifiedDoubleInterval.
64
+ :rc :contractiveDecay true.
65
+ }.
66
+
67
+ # ----------------
68
+ # Initial envelope
69
+ # ----------------
70
+
71
+ {
72
+ :rc :initialVoltage ?v0.
73
+ }
74
+ =>
75
+ {
76
+ :rc :voltageEnvelopeAt (0 ?v0 ?v0).
77
+ }.
78
+
79
+ # -------------------------------------
80
+ # Envelope propagation
81
+ # lower(k+1) = decayLower * lower(k)
82
+ # upper(k+1) = decayUpper * upper(k)
83
+ # -------------------------------------
84
+
85
+ {
86
+ :rc :maxStep ?max;
87
+ :decayLower ?aLo;
88
+ :decayUpper ?aHi.
89
+ :rc :voltageEnvelopeAt (?k ?lo ?hi).
90
+ ?k math:lessThan ?max.
91
+ ( ?k 1 ) math:sum ?k1.
92
+ ( ?aLo ?lo ) math:product ?lo1.
93
+ ( ?aHi ?hi ) math:product ?hi1.
94
+ }
95
+ =>
96
+ {
97
+ :rc :voltageEnvelopeAt (?k1 ?lo1 ?hi1).
98
+ }.
99
+
100
+ # -----------------------------
101
+ # The envelope shrinks strictly
102
+ # -----------------------------
103
+
104
+ {
105
+ :rc :voltageEnvelopeAt (?k ?lo ?hi).
106
+ ( ?k 1 ) math:sum ?k1.
107
+ :rc :voltageEnvelopeAt (?k1 ?lo1 ?hi1).
108
+ ?hi1 math:lessThan ?hi.
109
+ }
110
+ =>
111
+ {
112
+ :rc :strictContractionAt ?k.
113
+ }.
114
+
115
+ # --------------------------------
116
+ # Settlement in the tolerance band
117
+ # --------------------------------
118
+
119
+ {
120
+ :rc :voltageEnvelopeAt (?k ?lo ?hi).
121
+ :rc :tolerance ?tol.
122
+ ?hi math:lessThan ?tol.
123
+ }
124
+ =>
125
+ {
126
+ :rc :settledCandidate ?k.
127
+ }.
128
+
129
+ {
130
+ :rc :settledCandidate ?k.
131
+ ?k math:greaterThan 0.
132
+ ( ?k 1 ) math:difference ?km1.
133
+ :rc :voltageEnvelopeAt (?km1 ?prevLo ?prevHi).
134
+ :rc :tolerance ?tol.
135
+ ?prevHi math:notLessThan ?tol.
136
+ }
137
+ =>
138
+ {
139
+ :rc :firstSettledStep ?k.
140
+ }.
141
+
142
+ {
143
+ :rc :firstSettledStep ?k.
144
+ :rc :samplePeriod ?ts.
145
+ ( ?k ?ts ) math:product ?t.
146
+ }
147
+ =>
148
+ {
149
+ :rc :firstSettledTime ?t.
150
+ }.
151
+
152
+ # -----------------------------------------------------------
153
+ # Readable engineering summary for the floating-point witness
154
+ # -----------------------------------------------------------
155
+
156
+ {
157
+ :rc :firstSettledStep ?k;
158
+ :firstSettledTime ?t;
159
+ :tolerance ?tol;
160
+ :exactDecaySymbol ?sym;
161
+ :decayLower ?aLo;
162
+ :decayUpper ?aHi.
163
+ }
164
+ log:query
165
+ {
166
+ :result :summary (
167
+ "exact-decay" ?sym
168
+ "double-lower" ?aLo
169
+ "double-upper" ?aHi
170
+ "tolerance" ?tol
171
+ "first-settled-step" ?k
172
+ "first-settled-time-s" ?t
173
+ ).
174
+ }.
175
+
176
+ {
177
+ :rc :voltageEnvelopeAt (?k ?lo ?hi).
178
+ }
179
+ log:query
180
+ {
181
+ :result :envelope (?k ?lo ?hi).
182
+ }.
183
+
184
+ {
185
+ :rc :strictContractionAt ?k.
186
+ }
187
+ log:query
188
+ {
189
+ :result :contractionAt ?k.
190
+ }.
@@ -0,0 +1,195 @@
1
+ # =======================================================================================
2
+ # Floating-point-first transcendental servo envelope
3
+ #
4
+ # Why this example exists:
5
+ # It complements the integer-first and decimal-first examples with a version whose
6
+ # certifying arithmetic starts from floating-point literals.
7
+ #
8
+ # Physical story:
9
+ # A sampled first-order servo has error dynamics
10
+ #
11
+ # e(k+1) = a * e(k)
12
+ #
13
+ # with exact discrete pole
14
+ #
15
+ # a = exp(-Ts/tau) = exp(-1/3)
16
+ #
17
+ # for Ts = 20 ms and tau = 60 ms.
18
+ #
19
+ # The number exp(-1/3) is transcendental, so it is not available as a finite exact
20
+ # decimal or rational. In this example we work floating-point-first: the certificate is
21
+ # carried by N3 double literals, written in exponent form.
22
+ #
23
+ # Floating-point-first move:
24
+ # We store a certified double interval
25
+ #
26
+ # 7.165313105e-1 <= exp(-1/3) <= 7.165313106e-1
27
+ #
28
+ # and propagate a double error envelope. The resulting derivations stay explicit and
29
+ # machine-checkable, but now the numeric layer is “floating-point first”.
30
+ #
31
+ # What is certified:
32
+ # * the double interval is nonempty and contractive
33
+ # * the error envelope shrinks at every sample
34
+ # * from an initial error of 1.25e1, the loop is guaranteed inside 5.0e-1 by sample 10
35
+ # * with Ts = 2.0e-2 s, that means guaranteed settling by 2.0e-1 s
36
+ # =======================================================================================
37
+
38
+ @prefix : <http://example.org/floating-servo#>.
39
+ @prefix math: <http://www.w3.org/2000/10/swap/math#>.
40
+ @prefix log: <http://www.w3.org/2000/10/swap/log#>.
41
+
42
+ # ----------
43
+ # Parameters
44
+ # ----------
45
+
46
+ :servo a :SampledServoEnvelope;
47
+ :samplePeriod 2.0e-2;
48
+ :timeConstant 6.0e-2;
49
+ :exactPoleSymbol "exp(-1/3)";
50
+ :poleLower 7.165313105e-1;
51
+ :poleUpper 7.165313106e-1;
52
+ :initialAbsError 1.25e1;
53
+ :tolerance 5.0e-1;
54
+ :maxStep 12.
55
+
56
+ # ----------------------------------------------------------------
57
+ # The double interval is a finite certificate for a transcendental
58
+ # ----------------------------------------------------------------
59
+
60
+ {
61
+ :servo :poleLower ?lo; :poleUpper ?hi.
62
+ ?lo math:lessThan ?hi.
63
+ ?hi math:lessThan 1.0e0.
64
+ ?lo math:greaterThan 0.0e0.
65
+ }
66
+ =>
67
+ {
68
+ :servo :poleCertificate :CertifiedDoubleInterval.
69
+ :servo :contractivePole true.
70
+ }.
71
+
72
+ # ----------------
73
+ # Initial envelope
74
+ # ----------------
75
+
76
+ {
77
+ :servo :initialAbsError ?e0.
78
+ }
79
+ =>
80
+ {
81
+ :servo :errorEnvelopeAt (0 ?e0 ?e0).
82
+ }.
83
+
84
+ # -----------------------------------
85
+ # Envelope propagation
86
+ # lower(k+1) = poleLower * lower(k)
87
+ # upper(k+1) = poleUpper * upper(k)
88
+ # -----------------------------------
89
+
90
+ {
91
+ :servo :maxStep ?max;
92
+ :poleLower ?aLo;
93
+ :poleUpper ?aHi.
94
+ :servo :errorEnvelopeAt (?k ?lo ?hi).
95
+ ?k math:lessThan ?max.
96
+ ( ?k 1 ) math:sum ?k1.
97
+ ( ?aLo ?lo ) math:product ?lo1.
98
+ ( ?aHi ?hi ) math:product ?hi1.
99
+ }
100
+ =>
101
+ {
102
+ :servo :errorEnvelopeAt (?k1 ?lo1 ?hi1).
103
+ }.
104
+
105
+ # -----------------------------
106
+ # The envelope shrinks strictly
107
+ # -----------------------------
108
+
109
+ {
110
+ :servo :errorEnvelopeAt (?k ?lo ?hi).
111
+ ( ?k 1 ) math:sum ?k1.
112
+ :servo :errorEnvelopeAt (?k1 ?lo1 ?hi1).
113
+ ?hi1 math:lessThan ?hi.
114
+ }
115
+ =>
116
+ {
117
+ :servo :strictContractionAt ?k.
118
+ }.
119
+
120
+ # --------------------------------
121
+ # Settlement in the tolerance band
122
+ # --------------------------------
123
+
124
+ {
125
+ :servo :errorEnvelopeAt (?k ?lo ?hi).
126
+ :servo :tolerance ?tol.
127
+ ?hi math:lessThan ?tol.
128
+ }
129
+ =>
130
+ {
131
+ :servo :settledCandidate ?k.
132
+ }.
133
+
134
+ {
135
+ :servo :settledCandidate ?k.
136
+ ?k math:greaterThan 0.
137
+ ( ?k 1 ) math:difference ?km1.
138
+ :servo :errorEnvelopeAt (?km1 ?prevLo ?prevHi).
139
+ :servo :tolerance ?tol.
140
+ ?prevHi math:notLessThan ?tol.
141
+ }
142
+ =>
143
+ {
144
+ :servo :firstSettledStep ?k.
145
+ }.
146
+
147
+ {
148
+ :servo :firstSettledStep ?k.
149
+ :servo :samplePeriod ?ts.
150
+ ( ?k ?ts ) math:product ?t.
151
+ }
152
+ =>
153
+ {
154
+ :servo :firstSettledTime ?t.
155
+ }.
156
+
157
+ # ---------------------------------------------------------------
158
+ # Readable engineering summary for the floating-point certificate
159
+ # ---------------------------------------------------------------
160
+
161
+ {
162
+ :servo :firstSettledStep ?k;
163
+ :firstSettledTime ?t;
164
+ :tolerance ?tol;
165
+ :exactPoleSymbol ?sym;
166
+ :poleLower ?aLo;
167
+ :poleUpper ?aHi.
168
+ }
169
+ log:query
170
+ {
171
+ :result :summary (
172
+ "exact-pole" ?sym
173
+ "double-lower" ?aLo
174
+ "double-upper" ?aHi
175
+ "tolerance" ?tol
176
+ "first-settled-step" ?k
177
+ "first-settled-time-s" ?t
178
+ ).
179
+ }.
180
+
181
+ {
182
+ :servo :errorEnvelopeAt (?k ?lo ?hi).
183
+ }
184
+ log:query
185
+ {
186
+ :result :envelope (?k ?lo ?hi).
187
+ }.
188
+
189
+ {
190
+ :servo :strictContractionAt ?k.
191
+ }
192
+ log:query
193
+ {
194
+ :result :contractionAt ?k.
195
+ }.