eyeling 1.14.9 → 1.14.11
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/examples/e-computable-real.n3 +201 -0
- package/examples/euler-identity.n3 +113 -0
- package/examples/gd-step-certified.n3 +283 -0
- package/examples/hadamard-approx.n3 +287 -0
- package/examples/kronecker.n3 +118 -0
- package/examples/output/e-computable-real.n3 +93 -0
- package/examples/output/euler-identity.n3 +8 -0
- package/examples/output/gd-step-certified.n3 +82 -0
- package/examples/output/hadamard-approx.n3 +444 -0
- package/examples/output/kronecker.n3 +80 -0
- package/examples/output/pi-computable-real.n3 +94 -0
- package/examples/output/sqrt2-cauchy.n3 +57 -0
- package/examples/output/sqrt2-computable-real.n3 +68 -0
- package/examples/output/sqrt2-dedekind.n3 +108 -0
- package/examples/output/tgate-approx.n3 +339 -0
- package/examples/output/transcendental-families.n3 +26 -26
- package/examples/output/transcendental-names-and-families.n3 +27 -27
- package/examples/pi-computable-real.n3 +268 -0
- package/examples/sqrt2-cauchy.n3 +182 -0
- package/examples/sqrt2-computable-real.n3 +208 -0
- package/examples/sqrt2-dedekind.n3 +271 -0
- package/examples/tgate-approx.n3 +276 -0
- package/eyeling.js +98 -11
- package/lib/lexer.js +29 -0
- package/lib/parser.js +19 -2
- package/lib/printing.js +50 -9
- package/package.json +1 -1
- package/test/api.test.js +125 -0
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# =========================================================================================
|
|
2
|
+
# e as “integers-only” engineering: a computable real via factorial-series bounds
|
|
3
|
+
#
|
|
4
|
+
# Philosophy (Kronecker-friendly):
|
|
5
|
+
# We do not assume a completed continuum of real numbers. Instead, a “real number” is
|
|
6
|
+
# represented by a *procedure* that can deliver arbitrarily tight rational information
|
|
7
|
+
# on demand (finite request in, finite certificate out).
|
|
8
|
+
#
|
|
9
|
+
# What this file encodes:
|
|
10
|
+
# We represent e = exp(1) using the classical series:
|
|
11
|
+
# e = Σ_{k=0..∞} 1/k!
|
|
12
|
+
# For each requested precision n (0..maxN) we compute an index m = n + offset and produce
|
|
13
|
+
# a rational interval [L_n, U_n] where:
|
|
14
|
+
# L_n = Σ_{k=0..m} 1/k! (partial sum; lower bound)
|
|
15
|
+
# U_n = L_n + R_m (upper bound using a remainder estimate)
|
|
16
|
+
#
|
|
17
|
+
# Guarantees produced (machine-checkable inequalities):
|
|
18
|
+
# (1) width(n) = U_n - L_n = R_m
|
|
19
|
+
# (2) width(n) <= 2^-n (precision guarantee)
|
|
20
|
+
# (3) optional sanity: intervals are nested as n increases
|
|
21
|
+
#
|
|
22
|
+
# Finite arithmetic only:
|
|
23
|
+
# All computations are performed with finite numeric literals; rationals appear only as
|
|
24
|
+
# quotients produced by math:quotient (no “actual” infinite real object is required).
|
|
25
|
+
#
|
|
26
|
+
# Output discipline (Gödel-ish):
|
|
27
|
+
# The rules derive a closure; log:query is used to project only the intended results
|
|
28
|
+
# (bounds, widths, epsilons, midpoints), separating “truth definition” from “reporting”.
|
|
29
|
+
# =========================================================================================
|
|
30
|
+
|
|
31
|
+
@prefix : <http://example.org/kronecker-e#>.
|
|
32
|
+
@prefix math: <http://www.w3.org/2000/10/swap/math#>.
|
|
33
|
+
@prefix log: <http://www.w3.org/2000/10/swap/log#>.
|
|
34
|
+
|
|
35
|
+
# ----------
|
|
36
|
+
# Parameters
|
|
37
|
+
# ----------
|
|
38
|
+
|
|
39
|
+
:e a :ComputableReal;
|
|
40
|
+
:computedBy :seriesE.
|
|
41
|
+
|
|
42
|
+
:seriesE a :IntervalProcedure;
|
|
43
|
+
:maxN 12;
|
|
44
|
+
:offset 6;
|
|
45
|
+
:maxK 18. # must be >= maxN + offset
|
|
46
|
+
|
|
47
|
+
# ------------------------------------
|
|
48
|
+
# 1) Generate factorials: fact(k) = k!
|
|
49
|
+
# ------------------------------------
|
|
50
|
+
|
|
51
|
+
:seriesE :fact (0 1.0).
|
|
52
|
+
|
|
53
|
+
{
|
|
54
|
+
:seriesE :fact (?k ?f).
|
|
55
|
+
:seriesE :maxK ?maxK.
|
|
56
|
+
?k math:lessThan ?maxK.
|
|
57
|
+
|
|
58
|
+
( ?k 1 ) math:sum ?k1.
|
|
59
|
+
( ?f ?k1 ) math:product ?f1.
|
|
60
|
+
}
|
|
61
|
+
=>
|
|
62
|
+
{
|
|
63
|
+
:seriesE :fact (?k1 ?f1).
|
|
64
|
+
}.
|
|
65
|
+
|
|
66
|
+
# --------------------------------------------------
|
|
67
|
+
# 2) Generate partial sums: sum(k) = Σ_{i=0..k} 1/i!
|
|
68
|
+
# --------------------------------------------------
|
|
69
|
+
|
|
70
|
+
:seriesE :sum (0 1.0).
|
|
71
|
+
|
|
72
|
+
{
|
|
73
|
+
:seriesE :sum (?k ?s).
|
|
74
|
+
:seriesE :maxK ?maxK.
|
|
75
|
+
?k math:lessThan ?maxK.
|
|
76
|
+
|
|
77
|
+
( ?k 1 ) math:sum ?k1.
|
|
78
|
+
:seriesE :fact (?k1 ?f1).
|
|
79
|
+
|
|
80
|
+
( 1.0 ?f1 ) math:quotient ?term.
|
|
81
|
+
( ?s ?term ) math:sum ?s1.
|
|
82
|
+
}
|
|
83
|
+
=>
|
|
84
|
+
{
|
|
85
|
+
:seriesE :sum (?k1 ?s1).
|
|
86
|
+
}.
|
|
87
|
+
|
|
88
|
+
# ------------------------------------------
|
|
89
|
+
# 3) Generate precision requests n = 0..maxN
|
|
90
|
+
# ------------------------------------------
|
|
91
|
+
|
|
92
|
+
:seriesE :n 0.
|
|
93
|
+
|
|
94
|
+
{
|
|
95
|
+
:seriesE :n ?n.
|
|
96
|
+
:seriesE :maxN ?maxN.
|
|
97
|
+
?n math:lessThan ?maxN.
|
|
98
|
+
( ?n 1 ) math:sum ?n1.
|
|
99
|
+
}
|
|
100
|
+
=>
|
|
101
|
+
{
|
|
102
|
+
:seriesE :n ?n1.
|
|
103
|
+
}.
|
|
104
|
+
|
|
105
|
+
# ------------------------------------------------------------------
|
|
106
|
+
# 4) For each n, choose m = n + offset and compute bounds [L_n, U_n]
|
|
107
|
+
# Remainder estimate used here:
|
|
108
|
+
# R_m = 1 / (m * m!)
|
|
109
|
+
# (a standard upper bound for the tail of Σ 1/k! for m >= 1)
|
|
110
|
+
# ------------------------------------------------------------------
|
|
111
|
+
|
|
112
|
+
{
|
|
113
|
+
:seriesE :n ?n.
|
|
114
|
+
:seriesE :offset ?off.
|
|
115
|
+
( ?n ?off ) math:sum ?m.
|
|
116
|
+
|
|
117
|
+
:seriesE :sum (?m ?L).
|
|
118
|
+
:seriesE :fact (?m ?mf).
|
|
119
|
+
|
|
120
|
+
( ?m ?mf ) math:product ?den. # den = m * m!
|
|
121
|
+
( 1.0 ?den ) math:quotient ?R. # R = 1 / (m*m!)
|
|
122
|
+
( ?L ?R ) math:sum ?U. # U = L + R
|
|
123
|
+
}
|
|
124
|
+
=>
|
|
125
|
+
{
|
|
126
|
+
:e :bounds (?n ?m ?L ?U).
|
|
127
|
+
:e :width (?n ?R).
|
|
128
|
+
}.
|
|
129
|
+
|
|
130
|
+
# ---------------------------------------------------------------
|
|
131
|
+
# 5) eps(n) = 2^-n and the precision guarantee width(n) <= eps(n)
|
|
132
|
+
# ---------------------------------------------------------------
|
|
133
|
+
|
|
134
|
+
{
|
|
135
|
+
:seriesE :n ?n.
|
|
136
|
+
( 2 ?n ) math:exponentiation ?pow2.
|
|
137
|
+
( 1.0 ?pow2 ) math:quotient ?eps.
|
|
138
|
+
}
|
|
139
|
+
=>
|
|
140
|
+
{
|
|
141
|
+
:e :epsilon (?n ?eps).
|
|
142
|
+
}.
|
|
143
|
+
|
|
144
|
+
{
|
|
145
|
+
:e :width (?n ?W).
|
|
146
|
+
:e :epsilon (?n ?eps).
|
|
147
|
+
?W math:notGreaterThan ?eps.
|
|
148
|
+
}
|
|
149
|
+
=>
|
|
150
|
+
{
|
|
151
|
+
:e :guaranteeWidthLe2PowNegN (?n true).
|
|
152
|
+
}.
|
|
153
|
+
|
|
154
|
+
# ----------------------------------------------------------
|
|
155
|
+
# 6) Optional sanity: nestedness of intervals as n increases
|
|
156
|
+
# ----------------------------------------------------------
|
|
157
|
+
|
|
158
|
+
{
|
|
159
|
+
:e :bounds (?n ?m ?L ?U).
|
|
160
|
+
( ?n 1 ) math:sum ?n1.
|
|
161
|
+
:e :bounds (?n1 ?m1 ?L1 ?U1).
|
|
162
|
+
|
|
163
|
+
?L1 math:notLessThan ?L.
|
|
164
|
+
?U1 math:notGreaterThan ?U.
|
|
165
|
+
}
|
|
166
|
+
=>
|
|
167
|
+
{
|
|
168
|
+
:e :nested (?n1 true).
|
|
169
|
+
}.
|
|
170
|
+
|
|
171
|
+
# -------------------------------
|
|
172
|
+
# 7) Output selection (log:query)
|
|
173
|
+
# -------------------------------
|
|
174
|
+
|
|
175
|
+
{
|
|
176
|
+
:e :bounds (?n ?m ?L ?U).
|
|
177
|
+
:e :width (?n ?W).
|
|
178
|
+
:e :epsilon (?n ?eps).
|
|
179
|
+
:e :guaranteeWidthLe2PowNegN (?n true).
|
|
180
|
+
|
|
181
|
+
( ?L ?U ) math:sum ?s.
|
|
182
|
+
( ?s 2 ) math:quotient ?M.
|
|
183
|
+
( ?W 2 ) math:quotient ?errBound.
|
|
184
|
+
}
|
|
185
|
+
log:query
|
|
186
|
+
{
|
|
187
|
+
:result :requestN ?n.
|
|
188
|
+
:result :chosenM ?m.
|
|
189
|
+
:result :interval (?n ?L ?U).
|
|
190
|
+
:result :width (?n ?W).
|
|
191
|
+
:result :eps (?n ?eps).
|
|
192
|
+
:result :midpoint (?n ?M ?errBound).
|
|
193
|
+
}.
|
|
194
|
+
|
|
195
|
+
{
|
|
196
|
+
:e :nested (?n true).
|
|
197
|
+
}
|
|
198
|
+
log:query
|
|
199
|
+
{
|
|
200
|
+
:result :nestedAt (?n true).
|
|
201
|
+
}.
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# =========================================================================================
|
|
2
|
+
# Euler identity (exact, certificate-friendly):
|
|
3
|
+
# exp(i*pi) + 1 = 0
|
|
4
|
+
#
|
|
5
|
+
# Philosophy:
|
|
6
|
+
# Unlike the T-gate example, this phase needs no approximation. exp(i*pi) lands exactly at
|
|
7
|
+
# (-1,0) = cos(pi) + i sin(pi), so the identity can be certified using integer arithmetic
|
|
8
|
+
# alone.
|
|
9
|
+
#
|
|
10
|
+
# Method:
|
|
11
|
+
# 1) Construct -1 as 0 - 1.
|
|
12
|
+
# 2) Represent exp(i*pi) exactly as (-1, 0).
|
|
13
|
+
# 3) Add 1 componentwise to obtain (0, 0).
|
|
14
|
+
# 4) Sanity-check the phase modulus: |-1 + 0i|^2 = 1.
|
|
15
|
+
# 5) Project only the intended certificates via log:query.
|
|
16
|
+
# =========================================================================================
|
|
17
|
+
|
|
18
|
+
@prefix : <http://example.org/euler-identity#>.
|
|
19
|
+
@prefix log: <http://www.w3.org/2000/10/swap/log#>.
|
|
20
|
+
@prefix math: <http://www.w3.org/2000/10/swap/math#>.
|
|
21
|
+
|
|
22
|
+
# ----------
|
|
23
|
+
# Parameters
|
|
24
|
+
# ----------
|
|
25
|
+
|
|
26
|
+
:EulerIdentity a :ExactComplexEquation;
|
|
27
|
+
:name "Euler identity";
|
|
28
|
+
:formula "exp(i*pi) + 1 = 0";
|
|
29
|
+
:usesPhase :phasePi.
|
|
30
|
+
|
|
31
|
+
:one a :ComplexNumber;
|
|
32
|
+
:exact (1 0).
|
|
33
|
+
|
|
34
|
+
:zero a :ComplexNumber;
|
|
35
|
+
:exact (0 0).
|
|
36
|
+
|
|
37
|
+
:phasePi a :ComplexPhase;
|
|
38
|
+
:definedAs "cos(pi) + i sin(pi)".
|
|
39
|
+
|
|
40
|
+
# -----------------------------------------
|
|
41
|
+
# 1) Construct exp(i*pi) exactly as (-1, 0)
|
|
42
|
+
# -----------------------------------------
|
|
43
|
+
|
|
44
|
+
{
|
|
45
|
+
(0 1) math:difference ?minusOne.
|
|
46
|
+
} => {
|
|
47
|
+
:phasePi :exact (?minusOne 0).
|
|
48
|
+
}.
|
|
49
|
+
|
|
50
|
+
# -----------------------------------------------------
|
|
51
|
+
# 2) Add 1 componentwise: (-1 + 0i) + (1 + 0i) = 0 + 0i
|
|
52
|
+
# -----------------------------------------------------
|
|
53
|
+
|
|
54
|
+
{
|
|
55
|
+
:phasePi :exact (?re ?im).
|
|
56
|
+
:one :exact (?oneRe ?oneIm).
|
|
57
|
+
(?re ?oneRe) math:sum ?sumRe.
|
|
58
|
+
(?im ?oneIm) math:sum ?sumIm.
|
|
59
|
+
} => {
|
|
60
|
+
:EulerIdentity :lhsExact (?sumRe ?sumIm).
|
|
61
|
+
:EulerIdentity :rhsExact (0 0).
|
|
62
|
+
}.
|
|
63
|
+
|
|
64
|
+
# --------------------------------------------------
|
|
65
|
+
# 3) Certify that the left-hand side is exactly zero
|
|
66
|
+
# --------------------------------------------------
|
|
67
|
+
|
|
68
|
+
{
|
|
69
|
+
:EulerIdentity :lhsExact (?sumRe ?sumIm).
|
|
70
|
+
:zero :exact (?sumRe ?sumIm).
|
|
71
|
+
} => {
|
|
72
|
+
:EulerIdentity :holds true.
|
|
73
|
+
}.
|
|
74
|
+
|
|
75
|
+
# -------------------------------------------------
|
|
76
|
+
# 4) Sanity check: |exp(i*pi)|^2 = (-1)^2 + 0^2 = 1
|
|
77
|
+
# -------------------------------------------------
|
|
78
|
+
|
|
79
|
+
{
|
|
80
|
+
:phasePi :exact (?re ?im).
|
|
81
|
+
(?re ?re) math:product ?re2.
|
|
82
|
+
(?im ?im) math:product ?im2.
|
|
83
|
+
(?re2 ?im2) math:sum ?modSq.
|
|
84
|
+
} => {
|
|
85
|
+
:phasePi :modSq ?modSq.
|
|
86
|
+
}.
|
|
87
|
+
|
|
88
|
+
{
|
|
89
|
+
:phasePi :modSq ?modSq.
|
|
90
|
+
?modSq math:equalTo 1.
|
|
91
|
+
} => {
|
|
92
|
+
:phasePi :modSqIsOne true.
|
|
93
|
+
}.
|
|
94
|
+
|
|
95
|
+
# -------------------------------
|
|
96
|
+
# 5) Output selection (log:query)
|
|
97
|
+
# -------------------------------
|
|
98
|
+
|
|
99
|
+
{
|
|
100
|
+
:phasePi :exact (?re ?im).
|
|
101
|
+
:EulerIdentity :lhsExact (?sumRe ?sumIm).
|
|
102
|
+
:EulerIdentity :rhsExact (?rhsRe ?rhsIm).
|
|
103
|
+
:phasePi :modSq ?modSq.
|
|
104
|
+
:phasePi :modSqIsOne ?modOk.
|
|
105
|
+
:EulerIdentity :holds ?ok.
|
|
106
|
+
} log:query {
|
|
107
|
+
:result :phasePi (?re ?im).
|
|
108
|
+
:result :lhsPlusOne (?sumRe ?sumIm).
|
|
109
|
+
:result :rhsZero (?rhsRe ?rhsIm).
|
|
110
|
+
:result :phaseModSq ?modSq.
|
|
111
|
+
:result :phaseModSqIsOne ?modOk.
|
|
112
|
+
:result :identityHolds ?ok.
|
|
113
|
+
}.
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
# =========================================================================================
|
|
2
|
+
# A simple gradient descent step with certified rational bounds (integers-first style)
|
|
3
|
+
#
|
|
4
|
+
# Philosophy (Kronecker-friendly):
|
|
5
|
+
# We do not assume “true” real numbers as primitives. Instead, we represent quantities by
|
|
6
|
+
# finite rational/decimal literals and *certified interval bounds* derived by arithmetic.
|
|
7
|
+
#
|
|
8
|
+
# Objective (1D toy problem):
|
|
9
|
+
# f(x) = (x - a)^2 (convex quadratic with minimizer at x = a)
|
|
10
|
+
# ∇f(x) = 2 (x - a)
|
|
11
|
+
#
|
|
12
|
+
# Gradient descent update:
|
|
13
|
+
# x_{k+1} = x_k - η ∇f(x_k) = x_k - η * 2 (x_k - a)
|
|
14
|
+
#
|
|
15
|
+
# What is certified here:
|
|
16
|
+
# Given an interval x_k ∈ [L_k, U_k] and a step size η ≥ 0, we derive an interval
|
|
17
|
+
# x_{k+1} ∈ [L_{k+1}, U_{k+1}] by sound interval arithmetic:
|
|
18
|
+
# g ∈ [2(L_k-a), 2(U_k-a)]
|
|
19
|
+
# p = η g ∈ [η g_L, η g_U]
|
|
20
|
+
# x_{k+1} = x_k - p ∈ [L_k - p_U, U_k - p_L]
|
|
21
|
+
#
|
|
22
|
+
# Additionally (when η ≤ 1/2):
|
|
23
|
+
# the update map is monotone increasing (1 - 2η ≥ 0), and the interval width contracts:
|
|
24
|
+
# width_{k+1} ≤ width_k
|
|
25
|
+
#
|
|
26
|
+
# Output discipline (Gödel-ish):
|
|
27
|
+
# log:query projects only the intended results (bounds, midpoints, certificates).
|
|
28
|
+
# =========================================================================================
|
|
29
|
+
|
|
30
|
+
@prefix : <http://example.org/kronecker-gd#>.
|
|
31
|
+
@prefix math: <http://www.w3.org/2000/10/swap/math#>.
|
|
32
|
+
@prefix log: <http://www.w3.org/2000/10/swap/log#>.
|
|
33
|
+
|
|
34
|
+
# ----------
|
|
35
|
+
# Parameters
|
|
36
|
+
# ----------
|
|
37
|
+
|
|
38
|
+
:gd a :GradientDescentProcedure ;
|
|
39
|
+
:maxK 10 ;
|
|
40
|
+
:a 1.0 .
|
|
41
|
+
|
|
42
|
+
# Step size η = 1/5
|
|
43
|
+
{ ( 1.0 5 ) math:quotient ?eta. } => { :gd :eta ?eta. }.
|
|
44
|
+
|
|
45
|
+
# Initial uncertainty: x0 ∈ [0, 2]
|
|
46
|
+
:gd :xBounds (0 0.0 2.0).
|
|
47
|
+
|
|
48
|
+
# ----------------------------
|
|
49
|
+
# Generate indices k = 0..maxK
|
|
50
|
+
# ----------------------------
|
|
51
|
+
|
|
52
|
+
:gd :k 0.
|
|
53
|
+
|
|
54
|
+
{
|
|
55
|
+
:gd :k ?k.
|
|
56
|
+
:gd :maxK ?maxK.
|
|
57
|
+
?k math:lessThan ?maxK.
|
|
58
|
+
( ?k 1 ) math:sum ?k1.
|
|
59
|
+
}
|
|
60
|
+
=>
|
|
61
|
+
{
|
|
62
|
+
:gd :k ?k1.
|
|
63
|
+
}.
|
|
64
|
+
|
|
65
|
+
# ---------------------------------------
|
|
66
|
+
# A) Gradient bounds g ∈ [2(L-a), 2(U-a)]
|
|
67
|
+
# ---------------------------------------
|
|
68
|
+
|
|
69
|
+
{
|
|
70
|
+
:gd :a ?a.
|
|
71
|
+
:gd :xBounds (?k ?L ?U).
|
|
72
|
+
|
|
73
|
+
( ?L ?a ) math:difference ?dL.
|
|
74
|
+
( ?U ?a ) math:difference ?dU.
|
|
75
|
+
|
|
76
|
+
( 2 ?dL ) math:product ?gL.
|
|
77
|
+
( 2 ?dU ) math:product ?gU.
|
|
78
|
+
}
|
|
79
|
+
=>
|
|
80
|
+
{
|
|
81
|
+
:gd :gBounds (?k ?gL ?gU).
|
|
82
|
+
}.
|
|
83
|
+
|
|
84
|
+
# -----------------------------------------
|
|
85
|
+
# B) Step interval p = η g (η ≥ 0 assumed)
|
|
86
|
+
# -----------------------------------------
|
|
87
|
+
|
|
88
|
+
{
|
|
89
|
+
:gd :eta ?eta.
|
|
90
|
+
:gd :gBounds (?k ?gL ?gU).
|
|
91
|
+
|
|
92
|
+
( ?eta ?gL ) math:product ?pL.
|
|
93
|
+
( ?eta ?gU ) math:product ?pU.
|
|
94
|
+
}
|
|
95
|
+
=>
|
|
96
|
+
{
|
|
97
|
+
:gd :pBounds (?k ?pL ?pU).
|
|
98
|
+
}.
|
|
99
|
+
|
|
100
|
+
# --------------------------------------------
|
|
101
|
+
# C) Update bounds: x_{k+1} ∈ [L - pU, U - pL]
|
|
102
|
+
# --------------------------------------------
|
|
103
|
+
|
|
104
|
+
{
|
|
105
|
+
:gd :xBounds (?k ?L ?U).
|
|
106
|
+
:gd :pBounds (?k ?pL ?pU).
|
|
107
|
+
:gd :maxK ?maxK.
|
|
108
|
+
?k math:lessThan ?maxK.
|
|
109
|
+
|
|
110
|
+
( ?k 1 ) math:sum ?k1.
|
|
111
|
+
|
|
112
|
+
( ?L ?pU ) math:difference ?L1.
|
|
113
|
+
( ?U ?pL ) math:difference ?U1.
|
|
114
|
+
}
|
|
115
|
+
=>
|
|
116
|
+
{
|
|
117
|
+
:gd :xBounds (?k1 ?L1 ?U1).
|
|
118
|
+
}.
|
|
119
|
+
|
|
120
|
+
# -----------------------------
|
|
121
|
+
# D) Width + midpoint summaries
|
|
122
|
+
# -----------------------------
|
|
123
|
+
|
|
124
|
+
{
|
|
125
|
+
:gd :xBounds (?k ?L ?U).
|
|
126
|
+
|
|
127
|
+
( ?U ?L ) math:difference ?W.
|
|
128
|
+
( ?W 2 ) math:quotient ?halfW.
|
|
129
|
+
|
|
130
|
+
( ?L ?U ) math:sum ?s.
|
|
131
|
+
( ?s 2 ) math:quotient ?M.
|
|
132
|
+
}
|
|
133
|
+
=>
|
|
134
|
+
{
|
|
135
|
+
:gd :width (?k ?W).
|
|
136
|
+
:gd :midpoint (?k ?M ?halfW).
|
|
137
|
+
}.
|
|
138
|
+
|
|
139
|
+
# --------------------------------
|
|
140
|
+
# E) Optional certificate: η ≤ 1/2
|
|
141
|
+
# --------------------------------
|
|
142
|
+
|
|
143
|
+
{
|
|
144
|
+
:gd :eta ?eta.
|
|
145
|
+
( 1.0 2 ) math:quotient ?half.
|
|
146
|
+
?eta math:notGreaterThan ?half.
|
|
147
|
+
}
|
|
148
|
+
=>
|
|
149
|
+
{
|
|
150
|
+
:gd :etaLeHalf true.
|
|
151
|
+
}.
|
|
152
|
+
|
|
153
|
+
# width_{k+1} ≤ width_k when η ≤ 1/2 (checked from derived intervals)
|
|
154
|
+
{
|
|
155
|
+
:gd :etaLeHalf true.
|
|
156
|
+
:gd :width (?k ?W).
|
|
157
|
+
( ?k 1 ) math:sum ?k1.
|
|
158
|
+
:gd :width (?k1 ?W1).
|
|
159
|
+
?W1 math:notGreaterThan ?W.
|
|
160
|
+
}
|
|
161
|
+
=>
|
|
162
|
+
{
|
|
163
|
+
:gd :widthContractsAt (?k1 true).
|
|
164
|
+
}.
|
|
165
|
+
|
|
166
|
+
# ----------------------------------------------------------------
|
|
167
|
+
# F) Certified bounds on objective value f(x) = (x-a)^2 over [L,U]
|
|
168
|
+
# ----------------------------------------------------------------
|
|
169
|
+
|
|
170
|
+
# compute endpoint squares (L-a)^2 and (U-a)^2
|
|
171
|
+
{
|
|
172
|
+
:gd :a ?a.
|
|
173
|
+
:gd :xBounds (?k ?L ?U).
|
|
174
|
+
|
|
175
|
+
( ?L ?a ) math:difference ?dL.
|
|
176
|
+
( ?U ?a ) math:difference ?dU.
|
|
177
|
+
|
|
178
|
+
( ?dL ?dL ) math:product ?sL.
|
|
179
|
+
( ?dU ?dU ) math:product ?sU.
|
|
180
|
+
}
|
|
181
|
+
=>
|
|
182
|
+
{
|
|
183
|
+
:gd :endSquares (?k ?sL ?sU).
|
|
184
|
+
}.
|
|
185
|
+
|
|
186
|
+
# upper bound fU = max(sL,sU)
|
|
187
|
+
{
|
|
188
|
+
:gd :endSquares (?k ?sL ?sU).
|
|
189
|
+
( ?sL ?sU ) :max ?fU.
|
|
190
|
+
}
|
|
191
|
+
=>
|
|
192
|
+
{
|
|
193
|
+
:gd :fUpper (?k ?fU).
|
|
194
|
+
}.
|
|
195
|
+
|
|
196
|
+
# lower bound:
|
|
197
|
+
# if a ∈ [L,U] then fLower = 0
|
|
198
|
+
{
|
|
199
|
+
:gd :a ?a.
|
|
200
|
+
:gd :xBounds (?k ?L ?U).
|
|
201
|
+
?L math:notGreaterThan ?a.
|
|
202
|
+
?a math:notGreaterThan ?U.
|
|
203
|
+
}
|
|
204
|
+
=>
|
|
205
|
+
{
|
|
206
|
+
:gd :fLower (?k 0.0).
|
|
207
|
+
}.
|
|
208
|
+
|
|
209
|
+
# else if interval is entirely left of a (U < a): fLower = min(sL,sU)
|
|
210
|
+
{
|
|
211
|
+
:gd :a ?a.
|
|
212
|
+
:gd :xBounds (?k ?L ?U).
|
|
213
|
+
?U math:lessThan ?a.
|
|
214
|
+
:gd :endSquares (?k ?sL ?sU).
|
|
215
|
+
( ?sL ?sU ) :min ?fL.
|
|
216
|
+
}
|
|
217
|
+
=>
|
|
218
|
+
{
|
|
219
|
+
:gd :fLower (?k ?fL).
|
|
220
|
+
}.
|
|
221
|
+
|
|
222
|
+
# else if interval is entirely right of a (a < L): fLower = min(sL,sU)
|
|
223
|
+
{
|
|
224
|
+
:gd :a ?a.
|
|
225
|
+
:gd :xBounds (?k ?L ?U).
|
|
226
|
+
?a math:lessThan ?L.
|
|
227
|
+
:gd :endSquares (?k ?sL ?sU).
|
|
228
|
+
( ?sL ?sU ) :min ?fL.
|
|
229
|
+
}
|
|
230
|
+
=>
|
|
231
|
+
{
|
|
232
|
+
:gd :fLower (?k ?fL).
|
|
233
|
+
}.
|
|
234
|
+
|
|
235
|
+
# -------------------------------------------------------------------
|
|
236
|
+
# User-defined max/min
|
|
237
|
+
#
|
|
238
|
+
# These are written as backward rules (<=), so they behave like
|
|
239
|
+
# “user-defined built-ins” when you use (a b) :max ?m in a rule body.
|
|
240
|
+
# -------------------------------------------------------------------
|
|
241
|
+
|
|
242
|
+
{ ( ?a ?b ) :max ?a. } <= { ?a math:notLessThan ?b. }. # a >= b
|
|
243
|
+
{ ( ?a ?b ) :max ?b. } <= { ?a math:lessThan ?b. }. # a < b
|
|
244
|
+
|
|
245
|
+
{ ( ?a ?b ) :min ?a. } <= { ?a math:notGreaterThan ?b. }. # a <= b
|
|
246
|
+
{ ( ?a ?b ) :min ?b. } <= { ?a math:greaterThan ?b. }. # a > b
|
|
247
|
+
|
|
248
|
+
# ----------------------------
|
|
249
|
+
# Output selection (log:query)
|
|
250
|
+
# ----------------------------
|
|
251
|
+
|
|
252
|
+
{
|
|
253
|
+
:gd :k ?k.
|
|
254
|
+
:gd :xBounds (?k ?L ?U).
|
|
255
|
+
:gd :width (?k ?W).
|
|
256
|
+
:gd :midpoint (?k ?M ?halfW).
|
|
257
|
+
:gd :gBounds (?k ?gL ?gU).
|
|
258
|
+
:gd :pBounds (?k ?pL ?pU).
|
|
259
|
+
:gd :fLower (?k ?fL).
|
|
260
|
+
:gd :fUpper (?k ?fU).
|
|
261
|
+
}
|
|
262
|
+
log:query
|
|
263
|
+
{
|
|
264
|
+
:result :k ?k.
|
|
265
|
+
:result :xBounds (?k ?L ?U).
|
|
266
|
+
:result :midpoint (?k ?M ?halfW).
|
|
267
|
+
:result :width (?k ?W).
|
|
268
|
+
:result :gBounds (?k ?gL ?gU).
|
|
269
|
+
:result :pBounds (?k ?pL ?pU).
|
|
270
|
+
:result :fBounds (?k ?fL ?fU).
|
|
271
|
+
}.
|
|
272
|
+
|
|
273
|
+
{ :gd :eta ?eta. }
|
|
274
|
+
log:query
|
|
275
|
+
{ :result :eta ?eta. }.
|
|
276
|
+
|
|
277
|
+
{ :gd :etaLeHalf true. }
|
|
278
|
+
log:query
|
|
279
|
+
{ :result :etaLeHalf true. }.
|
|
280
|
+
|
|
281
|
+
{ :gd :widthContractsAt (?k true). }
|
|
282
|
+
log:query
|
|
283
|
+
{ :result :widthContractsAt (?k true). }.
|