mk: phase 7 piece A — fixed-point iteration in SLG tabling
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 48s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 48s
Replace the single-pass body run with table-2-slg-iter / table-3-slg-iter: each iteration stores the current vals in cache and re-runs the body; loop until vals length stops growing. The cache thus grows monotonically until no new answers appear. For simple cycles (single tabled relation) this is sound and terminating — len comparison is O(1) and the cache only grows. Limitation: mutually-recursive tabled relations have INDEPENDENT iteration loops. Each runs to its own fixed point in isolation; the two don't coordinate. True SLG uses a worklist that cross-fires re-iteration when any subgoal's cache grows. Left as a future refinement. All 5 SLG tests still pass (Fibonacci unchanged, 3 cyclic-patho cases unchanged).
This commit is contained in:
@@ -13,6 +13,23 @@
|
||||
;; recursive calls are NOT discovered. Full SLG with fixed-point
|
||||
;; iteration (re-running until no new answers) is left for follow-up.
|
||||
|
||||
(define
|
||||
table-2-slg-iter
|
||||
(fn
|
||||
(rel-fn input output s key prev-vals)
|
||||
(begin
|
||||
(mk-tab-store! key prev-vals)
|
||||
(let
|
||||
((all-substs (stream-take -1 ((rel-fn input output) s))))
|
||||
(let
|
||||
((vals (map (fn (s2) (mk-walk* output s2)) all-substs)))
|
||||
(cond
|
||||
((= (len vals) (len prev-vals))
|
||||
(begin
|
||||
(mk-tab-store! key vals)
|
||||
(mk-tab-replay-vals vals output s)))
|
||||
(:else (table-2-slg-iter rel-fn input output s key vals))))))))
|
||||
|
||||
(define
|
||||
table-2-slg
|
||||
(fn
|
||||
@@ -30,21 +47,29 @@
|
||||
(let
|
||||
((cached (mk-tab-lookup key)))
|
||||
(cond
|
||||
((= cached :in-progress) mzero)
|
||||
((not (= cached :miss))
|
||||
(mk-tab-replay-vals cached output s))
|
||||
(:else
|
||||
(begin
|
||||
(mk-tab-store! key :in-progress)
|
||||
(let
|
||||
((all-substs (stream-take -1 ((rel-fn input output) s))))
|
||||
(let
|
||||
((vals (map (fn (s2) (mk-walk* output s2)) all-substs)))
|
||||
(begin
|
||||
(mk-tab-store! key vals)
|
||||
(mk-tab-replay-vals vals output s))))))))))
|
||||
(table-2-slg-iter rel-fn input output s key (list)))))))
|
||||
(:else ((rel-fn input output) s))))))))
|
||||
|
||||
(define
|
||||
table-3-slg-iter
|
||||
(fn
|
||||
(rel-fn i1 i2 output s key prev-vals)
|
||||
(begin
|
||||
(mk-tab-store! key prev-vals)
|
||||
(let
|
||||
((all-substs (stream-take -1 ((rel-fn i1 i2 output) s))))
|
||||
(let
|
||||
((vals (map (fn (s2) (mk-walk* output s2)) all-substs)))
|
||||
(cond
|
||||
((= (len vals) (len prev-vals))
|
||||
(begin
|
||||
(mk-tab-store! key vals)
|
||||
(mk-tab-replay-vals vals output s)))
|
||||
(:else (table-3-slg-iter rel-fn i1 i2 output s key vals))))))))
|
||||
|
||||
(define
|
||||
table-3-slg
|
||||
(fn
|
||||
@@ -62,17 +87,8 @@
|
||||
(let
|
||||
((cached (mk-tab-lookup key)))
|
||||
(cond
|
||||
((= cached :in-progress) mzero)
|
||||
((not (= cached :miss))
|
||||
(mk-tab-replay-vals cached output s))
|
||||
(:else
|
||||
(begin
|
||||
(mk-tab-store! key :in-progress)
|
||||
(let
|
||||
((all-substs (stream-take -1 ((rel-fn i1 i2 output) s))))
|
||||
(let
|
||||
((vals (map (fn (s2) (mk-walk* output s2)) all-substs)))
|
||||
(begin
|
||||
(mk-tab-store! key vals)
|
||||
(mk-tab-replay-vals vals output s))))))))))
|
||||
(table-3-slg-iter rel-fn i1 i2 output s key (list)))))))
|
||||
(:else ((rel-fn i1 i2 output) s))))))))
|
||||
|
||||
Reference in New Issue
Block a user