:: :::: :: :- %say |= {^ {{typ/type gen/hoon ~} ~}} =< :- %noun =+ pro=(~(mint ut typ) %noun gen) ~_ (~(dunk ut typ) 'blow-subject') =+ bus=(bran:musk typ) ~& [%subject-mask mask.bus] =+ jon=(apex:musk bus q.pro) ?~ jon ~& %constant-stopped !! ?. ?=(%& -.u.jon) ~& %constant-blocked !! :: [p.pro [%1 p.u.jon]] p.u.jon |% ++ musk :: nock with block set => |% ++ block :: identity of resource awaited :: XX parameterize noun :: ++ result :: internal interpreter result :: $@(~ seminoun) :: ++ seminoun :: partial noun; blocked subtrees are ~ :: {mask/stencil data/noun} :: ++ stencil :: noun knowledge map :: $% :: no; noun has partial block substructure :: {%| left/stencil rite/stencil} :: yes; noun is either fully complete, or fully blocked :: {%& blocks/(set block)} == :: ++ output :: nil; interpreter stopped :: %- unit :: yes, complete noun; no, list of blocks :: (each noun (list block)) -- |% ++ bran |= sut/type =+ gil=*(set type) |- ^- seminoun ?- sut $noun [&+[~ ~ ~] ~] $void [&+[~ ~ ~] ~] {$atom *} ?~(q.sut [&+[~ ~ ~] ~] [&+~ u.q.sut]) {$cell *} (combine $(sut p.sut) $(sut q.sut)) {$core *} %+ combine:musk ?~ p.s.q.sut [&+[~ ~ ~] ~] [&+~ p.s.q.sut] $(sut p.sut) {$face *} $(sut ~(repo ut sut)) {$fork *} [&+[~ ~ ~] ~] {$help *} $(sut ~(repo ut sut)) {$hold *} ?: (~(has in gil) sut) [&+[~ ~ ~] ~] $(sut ~(repo ut sut), gil (~(put in gil) sut)) == ++ abet :: simplify raw result :: |= $: :: noy: raw result :: noy/result == ^- output :: propagate stop :: ?~ noy ~ :- ~ :: merge all blocking sets :: =/ blocks (squash mask.noy) ?: =(~ blocks) :: no blocks, data is complete :: &+data.noy :: reduce block set to block list :: |+~(tap in blocks) :: ++ apex :: execute nock on partial subject :: |= $: :: bus: subject, a partial noun :: fol: formula, a complete noun :: bus/seminoun fol/noun == ^- output :: simplify result :: %- abet :: interpreter loop :: |- ^- result :: ~& [%apex-fol fol] :: ~& [%apex-mac mask.bus] :: =- ~& [%apex-pro-mac ?@(foo ~ ~!(foo mask.foo))] :: foo :: ^= foo :: ^- result ?@ fol :: bad formula, stop :: ~ ?: ?=(^ -.fol) :: hed: interpret head :: =+ hed=$(fol -.fol) :: propagate stop :: ?~ hed ~ :: tal: interpret tail :: =+ tal=$(fol +.fol) :: propagate stop :: ?~ tal ~ :: combine :: (combine hed tal) ?+ fol :: bad formula; stop :: ~ :: 0; fragment :: {$0 b/@} :: if bad axis, stop :: ?: =(0 b.fol) ~ :: reduce to fragment :: (fragment b.fol bus) :: :: 1; constant :: {$1 b/*} :: constant is complete :: [&+~ b.fol] :: :: 2; recursion :: {$2 b/* c/*} :: require complete formula :: %+ require :: compute formula with current subject :: $(fol c.fol) |= :: ryf: next formula :: ryf/noun :: lub: next subject :: =+ lub=^$(fol b.fol) :: propagate stop :: ?~ lub ~ :: recurse :: ^$(fol ryf, bus lub) :: :: 3; probe :: {$3 b/*} %+ require $(fol b.fol) |= :: fig: probe input :: fig/noun :: yes if cell, no if atom :: [&+~ .?(fig)] :: :: 4; increment :: {$4 b/*} %+ require $(fol b.fol) |= :: fig: increment input :: fig/noun :: stop for cells, increment for atoms :: ?^(fig ~ [&+~ +(fig)]) :: :: 5; compare :: {$5 b/*} %+ require $(fol b.fol) |= :: fig: operator input :: fig/noun :: stop for atoms, compare cells :: ?@(fig ~ [&+~ =(-.fig +.fig)]) :: :: 6; if-then-else :: {$6 b/* c/* d/*} :: use standard macro expansion (slow) :: $(fol =>(fol [2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b])) :: :: 7; composition :: {$7 b/* c/*} :: use standard macro expansion (slow) :: $(fol =>(fol [2 b 1 c])) :: :: 8; declaration :: {$8 b/* c/*} :: use standard macro expansion (slow) :: $(fol =>(fol [7 [[7 [0 1] b] 0 1] c])) :: :: 9; invocation :: {$9 b/* c/*} :: use standard macro expansion (slow) :: $(fol =>(fol [7 c 2 [0 1] 0 b])) :: :: 10; static hint :: {$10 @ c/*} :: ignore hint :: $(fol c.fol) :: :: 10; dynamic hint :: {$10 {b/* c/*} d/*} :: noy: dynamic hint :: =+ noy=$(fol c.fol) :: propagate stop :: ?~ noy ~ :: otherwise, ignore hint :: $(fol d.fol) == :: ++ combine :: combine a pair of seminouns :: |= $: :: hed: head of pair :: tal: tail of pair :: hed/seminoun tal/seminoun == ^- seminoun ?. ?& &(?=(%& -.mask.hed) ?=(%& -.mask.tal)) =(=(~ blocks.mask.hed) =(~ blocks.mask.tal)) == :: default merge :: [|+[mask.hed mask.tal] [data.hed data.tal]] :: both sides total :: ?: =(~ blocks.mask.hed) :: both sides are complete :: [&+~ data.hed data.tal] :: both sides are blocked :: [&+(~(uni in blocks.mask.hed) blocks.mask.tal) ~] :: ++ fragment :: seek to an axis in a seminoun :: |= $: :: axe: tree address of subtree :: bus: partial noun :: axe/axis bus/seminoun == |- ^- result :: 1 is the root :: ?: =(1 axe) bus :: now: 2 or 3, top of axis :: lat: rest of axis :: =+ [now=(cap axe) lat=(mas axe)] ?- -.mask.bus :: subject is fully blocked or complete :: %& :: if fully blocked, produce self :: ?^ blocks.mask.bus bus :: descending into atom, stop :: ?@ data.bus ~ :: descend into complete cell :: $(axe lat, bus [&+~ ?:(=(2 now) -.data.bus +.data.bus)]) :: subject is partly blocked :: %| :: descend into partial cell :: %= $ axe lat bus ?: =(2 now) [left.mask.bus -.data.bus] [rite.mask.bus +.data.bus] == == :: require complete intermediate step :: ++ require |= $: noy/result yen/$-(noun result) == ^- result :: propagate stop :: ?~ noy ~ :: if partial block, squash blocks and stop :: ?: ?=(%| -.mask.noy) [&+(squash mask.noy) ~] :: if full block, propagate block :: ?: ?=(^ blocks.mask.noy) [mask.noy ~] :: otherwise use complete noun :: (yen data.noy) :: ++ squash :: convert stencil to block set :: |= tyn/stencil ^- (set block) ?- -.tyn %& blocks.tyn %| (~(uni in $(tyn left.tyn)) $(tyn rite.tyn)) == -- --