Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
180 commits
Select commit Hold shift + click to select a range
e3e8260
Hugr: move parent pointer outside of node
acl-cqc Dec 16, 2025
8b26471
Make abstract datatype for Hugr
acl-cqc Dec 16, 2025
990e261
WIP inline the one -!, abandon FreshMonad
acl-cqc Dec 16, 2025
214333b
Fix Hugr on NodeId, move Namespace inside -> freshNodeWithParent
acl-cqc Dec 16, 2025
33a498c
WIP inline withIO
acl-cqc Dec 17, 2025
99a7416
refactor: lift compileNode up to top level
acl-cqc Dec 17, 2025
5ec4c67
Revert "refactor: lift compileNode up to top level"
acl-cqc Dec 17, 2025
b9be70d
Separate out compilation of Source - fails 3 tests
acl-cqc Dec 17, 2025
4f3d1ff
Fix Eval not respecting liftedOutPorts -> just 1 fail
acl-cqc Dec 17, 2025
5e4ee49
And splices should use getOutPort too
acl-cqc Dec 17, 2025
af49caf
xfail remaining failure in closures.brat
acl-cqc Dec 17, 2025
8b74892
fixup! Separate out
acl-cqc Dec 17, 2025
1e9e1f2
refactor out compileInEdges
acl-cqc Dec 17, 2025
33eb452
refactor in_edges to top-level
acl-cqc Dec 17, 2025
d42778d
Separate out compilation of Target
acl-cqc Dec 17, 2025
57c2df7
refactor: compileKernBox takes src+tgt (Name, Name)
acl-cqc Dec 17, 2025
41b913f
Rename: freshNodeWithParent -> freshNode
acl-cqc Dec 17, 2025
df8b4dd
makeCS takes Hugr
acl-cqc Dec 18, 2025
1cfebd1
compileBox takes Container = 3*NodeId, uses setOp; {freshNode,new}WithIO
acl-cqc Dec 18, 2025
57f2110
HugrGraph: separate out root
acl-cqc Dec 18, 2025
a791530
HugrGraph: add io_children (written not read)
acl-cqc Dec 18, 2025
e6cecd7
WIP use io_children to sort Hugr. Fails on Conditionals - cases in wr…
acl-cqc Dec 18, 2025
af23d7e
hack setFirstChildren to get Cases in order inside Conditional
acl-cqc Dec 18, 2025
5d0d815
Drop unused instance Ord, and index inside OpCase
acl-cqc Dec 18, 2025
d7ae859
Hugr->HugrGraph
acl-cqc Dec 19, 2025
c2cee45
Remove HugrGraph.freshNodeWithIO
acl-cqc Dec 19, 2025
cf5f705
Move Container from HugrGraph to Compile/Hugr
acl-cqc Dec 19, 2025
c50cbb7
new returns just HugrGraph, expose root accessor
acl-cqc Dec 19, 2025
3f3c06d
io_children->first_children stores any number
acl-cqc Dec 19, 2025
365dddc
ake HugrGraph ops in State HugrGraph, Compile use onHugr
acl-cqc Dec 20, 2025
cb31461
HugrGraph.hs: do not re-export PortId
acl-cqc Dec 22, 2025
b88878a
reduce imports from Naming
acl-cqc Dec 22, 2025
446d978
Move renameAndSort inside serialize
acl-cqc Dec 22, 2025
cac91fe
Honour first_children of root
acl-cqc Dec 22, 2025
f053569
HugrGraph.rs: add splice
acl-cqc Dec 22, 2025
4b25c84
refactor previous
acl-cqc Dec 22, 2025
109cbe2
Add test, and some debugging info
acl-cqc Dec 22, 2025
f0482a6
add isHole, test there are no holes in resHugr
acl-cqc Dec 24, 2025
0369fbf
Add inlineDFG
acl-cqc Dec 24, 2025
7c6c608
Parametrize test both with and without inlining
acl-cqc Dec 24, 2025
6b6ba8c
WIP add Machine.hs
acl-cqc Dec 9, 2025
72d8527
Evaluates constant 4
acl-cqc Dec 9, 2025
18a60e0
And simple arithmetic
acl-cqc Dec 9, 2025
c5a23d0
WIP Eval, Box with captureSets and ReturnTo
acl-cqc Dec 9, 2025
b953fe1
start pattern matching - works if no tests
acl-cqc Dec 9, 2025
33a8345
The test file I've been using
acl-cqc Dec 9, 2025
085ef76
Do tests for pattern matching
croyzor Dec 9, 2025
1e112fc
Tests for vector even/odd tests (example falls over)
croyzor Dec 10, 2025
b81c28e
tracing the machine
conormcb Dec 10, 2025
d3ba753
Eval constructors
croyzor Dec 10, 2025
5d23571
WIP remove Brat-specific compilation
acl-cqc Jan 2, 2026
5bcc324
And a bit more
acl-cqc Jan 2, 2026
d2676c8
Simplify: all decls require extra-call
acl-cqc Jan 2, 2026
c5e3036
WIP expose only compileKernel, fix holes. direct calls WTF??
acl-cqc Jan 2, 2026
8b937fe
Remove CaptureSets
acl-cqc Jan 2, 2026
34ed063
Ah - kernels were inside Value::Constants, so could never have called…
acl-cqc Jan 2, 2026
12c14c9
compile only kernel boxes, return map name -> bytes+[splice]; many in…
acl-cqc Jan 2, 2026
9b80320
compileKernel returns HugrGraph, dump_json->HG.to_json, tidy imports
acl-cqc Jan 2, 2026
7137722
Interpreter compileKernel+splice. Compiles but does it work!? TODO ch…
acl-cqc Jan 2, 2026
f181da4
Eval unification inputs in pattern matching; add dummy value for *; f…
croyzor Dec 10, 2025
b116c84
print json, + fixes: evalSplices Use->Finished, handle CQubit
acl-cqc Jan 9, 2026
a960fbb
Compile toplevel kernels only
acl-cqc Jan 9, 2026
5416be8
Review comment: M.alter in addToMap
acl-cqc Jan 10, 2026
36ae9d1
Review comment: check only single in-edges
acl-cqc Jan 10, 2026
a4523af
Review comments: state->modify, parent->defNode, foldl'
acl-cqc Jan 10, 2026
f691012
comments
acl-cqc Jan 10, 2026
d2e5473
WIP HugrGraph.hs separate Namespace
acl-cqc Jan 10, 2026
10e3abd
Move Namespace out of HugrGraph into Compile monad
acl-cqc Jan 10, 2026
673d664
Parametrize HugrGraph by nodeid for methods that don't use Namespace
acl-cqc Jan 10, 2026
1e34f29
hide HG.edgeList
acl-cqc Jan 10, 2026
00b4b16
comment issue 101
acl-cqc Jan 12, 2026
3404672
Merge remote-tracking branch 'origin/main' into refactor/hugr_graph
acl-cqc Jan 12, 2026
9d9bd68
Merge branch 'refactor/hugr_graph' into acl/splice_hugr
acl-cqc Jan 13, 2026
2b953b3
Comment what splice/inlineDFG do
acl-cqc Jan 16, 2026
d244141
Turn off tracing
croyzor Feb 23, 2026
ab928df
Renaming frames
croyzor Feb 25, 2026
3571256
rename union -> disjoint union, use more
acl-cqc Feb 25, 2026
ff54a49
Merge remote-tracking branch 'origin/main' into acl/splice_hugr
acl-cqc Feb 25, 2026
6e35999
Merge branch 'acl/splice_hugr' into acl/stack_machine2
acl-cqc Feb 25, 2026
8b21e2b
Fix input naming bug in makeIO
croyzor Feb 25, 2026
db17d09
Better `Show` instance for `Frame`
croyzor Feb 25, 2026
3694660
Fix bug in `addEdge` (`parents` contains all nodes; `nodes` doesn't!)
croyzor Feb 25, 2026
88b2a8f
Hack CR* gates into BRAT extension (for now!)
croyzor Feb 25, 2026
0385c65
Add hugr rotation helpers
croyzor Feb 25, 2026
b490ca1
Handle Prim ops in the machine
croyzor Feb 25, 2026
0fdacbc
Done TODO
acl-cqc Feb 27, 2026
5b55246
Merge remote-tracking branch 'origin/main' into acl/stack_machine2
acl-cqc Mar 6, 2026
7148d10
Pull thinnings code
croyzor Apr 14, 2026
988f4d3
Pull new test from thinning branch
croyzor Apr 14, 2026
4c8e780
Update golden values, and don't XFAIL thin.brat
croyzor Apr 14, 2026
174dd33
Remove irrelevant `Eq` type code
croyzor Apr 14, 2026
98f12a0
Handle thinnings in the machine
croyzor Apr 14, 2026
90ebbc7
Exercise composition
croyzor Apr 14, 2026
d3c6495
Show instance for Thinning values
croyzor Apr 14, 2026
32ed2a4
Refactor endPorts polarity
croyzor Apr 14, 2026
b395cb0
Pass `Yield` and error message for if it isn't unstuck
croyzor Apr 14, 2026
03e7226
Prepare to give and demand constraints
croyzor Apr 14, 2026
646b3cc
Combine parsing tests into checking
acl-cqc Apr 14, 2026
bfef2e0
Calculate checking XFAILs from file header, but still have list for c…
acl-cqc Apr 14, 2026
b1478f6
Remove unused nonCompilingExamples, also invalidExamples mechanism
acl-cqc Apr 14, 2026
4245b0b
Two lists via struct, expect parsing to succeed for xfail-checking
acl-cqc Apr 14, 2026
a75ca1a
Integrate compile tests into checking (--!xfail-compilation)
acl-cqc Apr 14, 2026
aa1afac
Get to wits end with constraints
croyzor Apr 15, 2026
0dbeba0
Delete constraints from rows
croyzor Apr 15, 2026
fe91e5f
Remove old separate compilation tests
acl-cqc Apr 17, 2026
c54dd8e
Remove expected lists from haskell
acl-cqc Apr 14, 2026
ea17d12
Separate out Checking.hs from Examples.hs
acl-cqc Apr 17, 2026
ddb2af0
WIP Execution tests parsed out of file, reading func_name from next l…
acl-cqc Apr 15, 2026
abd49a1
runInterpreter returns ByteString, avoid capture/golden
acl-cqc Apr 17, 2026
5a014a9
more tests in examples/arith.brat (remove arith.brat)
acl-cqc Apr 17, 2026
5cbf449
Use Data.Aeson.Text encodeToLazyText
acl-cqc Apr 17, 2026
bba87c6
Update to tasty-1.5
croyzor Apr 17, 2026
3ea59a5
combine check+exec tests into sequentialTestGroup from tasty-1.5
acl-cqc Apr 17, 2026
3aea4e8
regroup parse+check+compile+exec under each example
acl-cqc Apr 17, 2026
3cf7052
simplify by allowing singleton group, but parallelize execution tests
acl-cqc Apr 17, 2026
3cbf05a
Re-enable warnings, fix
acl-cqc Apr 17, 2026
f4041a4
Get rid of problematic filter for _X in overs
croyzor Apr 20, 2026
19501fa
Parse Eqn as type instead of constraint kind
croyzor Apr 20, 2026
88505b1
Kind check Eqn : *
croyzor Apr 20, 2026
57d3f70
(wip, tracing): towards constraint solving
croyzor Apr 20, 2026
5af9f37
Remove the putStrLn 'Not an Id node', make 'not found in VEnv' an error
acl-cqc Apr 20, 2026
55e3929
Change --!test to --!exec w/option -xfail, add tests in app.brat
acl-cqc Apr 20, 2026
74a01a6
Add xfails (Suspend): brace-sections, batcher-merge-sort, cons, fanou…
acl-cqc Apr 20, 2026
f30f52b
infer{,2}.brat: remove repeated/commented-out-repeats, inc. of eatsfu…
acl-cqc Apr 20, 2026
85c2cfb
Solve constraints of fulbourn numbers
croyzor Apr 20, 2026
977c695
infer.brat: add vector tests (passing w/ typechecking workaround)
acl-cqc Apr 20, 2026
501da84
infer2.brat: tests that work
acl-cqc Apr 20, 2026
2b055cb
infer2.brat: tests that produce wrong answer - suspect wrong graph
acl-cqc Apr 21, 2026
56fee11
Revert "infer2.brat: tests that produce wrong answer - suspect wrong …
acl-cqc Apr 21, 2026
31acde4
infer2.brat: test that fails with 'index too large' in Machine.hs
acl-cqc Apr 21, 2026
0c66214
Rm map.brat, included in infer.brat
acl-cqc Apr 21, 2026
eb88823
runInterpreter returns either Text or HugrGraph
acl-cqc Apr 21, 2026
070982f
HugrGraph: hide root, add getRoot/getNodes
acl-cqc Apr 21, 2026
6c82366
Test/Compile/Hugr.hs: add getSplices, compileToOutput checks they match
acl-cqc Apr 21, 2026
b2c624c
add --!exec-hugr that checks no splices, writes to test/examples/outp…
acl-cqc Apr 21, 2026
ba113a7
Fix bogus add def in examples
croyzor Apr 21, 2026
d6942bc
Machine: Add list constructors to pattern matching
croyzor Apr 21, 2026
83d27b2
xfail remaining tests
croyzor Apr 21, 2026
3407191
infer2.brat: xfailed tests that produce wrong answer - suspect wrong …
acl-cqc Apr 21, 2026
f267f4a
move examples output
acl-cqc Apr 22, 2026
3c0571a
Fix adder.brat test
croyzor Apr 22, 2026
91bfde2
Remove undercooked hea example
croyzor Apr 22, 2026
37f2209
Fix infer_thunks exec tests
croyzor Apr 22, 2026
2bf2238
Delete redundant karlheinz_alias test
croyzor Apr 22, 2026
b0457aa
Add missing extension to brat_extension
croyzor Apr 22, 2026
2a2b7c6
Merge branch 'main' into acl/stack_machine2
croyzor Apr 22, 2026
0f7679b
No point in CompilationResult returning OutPorts of lost Graph; getSp…
acl-cqc Apr 22, 2026
b81b2c6
clarify xfail comment
acl-cqc Apr 22, 2026
b82e277
add tiny hugr test in kernel.brat
acl-cqc Apr 22, 2026
289f19d
simplify some funcs in Compiler.hs
acl-cqc Apr 22, 2026
493e890
Get fanout test running
croyzor Apr 22, 2026
d17da8e
Expand link in comment
croyzor Apr 22, 2026
43bb48a
Add missing cases to Machine
croyzor Apr 22, 2026
febbf79
[WIP] bits and pieces for implementing MapFun in Machine
croyzor Apr 22, 2026
9a4a05e
implement MapFun, factor out runThunk
acl-cqc Apr 22, 2026
4997694
VectorisedFuncs (frame), plus runVectorisedThunks -> test passes
acl-cqc Apr 22, 2026
237b94e
More vectorise tests
croyzor Apr 22, 2026
4caa9dd
more batcher tests
acl-cqc Apr 22, 2026
fdb7aa1
refactor: rm runThunk
acl-cqc Apr 22, 2026
1952ed7
vector of Value not BratThunk, hopefully handles >1D
acl-cqc Apr 22, 2026
3e64526
Machine: Dig for appropriate vectorised function
croyzor Apr 22, 2026
7d3135e
StringV
croyzor Apr 22, 2026
a878b75
Remove VecThunkV, add BratThunk::VectorisedThunks
acl-cqc Apr 22, 2026
790f326
Merge commit 'a878b75e' into acl/stack_machine2
acl-cqc Apr 22, 2026
e6d10ea
dig inside getVecs
acl-cqc Apr 23, 2026
aafb9bb
use MapM in Maybe monad for getVecs+getThunks
acl-cqc Apr 23, 2026
70870c6
comment
acl-cqc Apr 23, 2026
faf03c4
cons.brat whitespace
acl-cqc Apr 24, 2026
b12abad
reinstate hea.brat
acl-cqc Apr 24, 2026
ffd0613
lookupOutport looks only in local BratValues
acl-cqc Apr 24, 2026
8f56da2
comments
acl-cqc Apr 24, 2026
1b61797
EvalPort -> evalPort
acl-cqc Apr 24, 2026
ae9b271
EvalNode -> evalNode
acl-cqc Apr 24, 2026
695f66f
Merge remote-tracking branch 'origin/main' into acl/stack_machine2
acl-cqc Apr 24, 2026
53ee32a
Merge branch 'acl/stack_machine2' into thinnings_on_stack_machine
acl-cqc Apr 24, 2026
fdaa992
arith scheduling
croyzor Apr 21, 2026
d1cc270
Arith scheduling
croyzor Apr 24, 2026
d2fc53d
Cleanup
croyzor Apr 24, 2026
c350807
buggin & debuggin
croyzor Apr 21, 2026
990b131
examples for debugging
croyzor Apr 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 150 additions & 21 deletions brat/Brat/Checker.hs
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,22 @@ module Brat.Checker (checkBody
import Control.Monad (foldM, forM, zipWithM_)
import Control.Monad.Freer
import Data.Bifunctor
import Data.Foldable (for_)
import Data.Foldable (for_, traverse_)
import Data.Functor (($>), (<&>))
import Data.List ((\\), intercalate)
import Data.List.NonEmpty (NonEmpty(..))
import qualified Data.List.NonEmpty as NE
import qualified Data.Map as M
import Data.Maybe (fromJust)
import qualified Data.Set as S
import Data.Traversable (for)
import Data.Type.Equality ((:~:)(..), testEquality)
import Prelude hiding (filter)

import Brat.Checker.Helpers
import Brat.Checker.Monad
import Brat.Checker.Quantity
import Brat.Checker.SolveConstraints (fulbournConstraint, simplify)
import Brat.Checker.SolveHoles (typeEq)
import Brat.Checker.SolvePatterns (argProblems, argProblemsWithLeftovers, solve, typeOfEnd)
import Brat.Checker.Types
Expand All @@ -48,7 +50,9 @@ import Brat.Syntax.Simple
import Brat.Syntax.Value
import Bwd
import Hasochism
import Util (zipSameLength)
import Util (log2, zipSameLength)

import Debug.Trace

-- Put things into a standard form in a kind-directed manner, such that it is
-- meaningful to do case analysis on them
Expand Down Expand Up @@ -231,6 +235,11 @@ check' (Lambda c@(WC abstFC abst, body) cs) (overs, unders) = do
let srcMap = fromJust $ zipSameLength (fst <$> usedOvers) (fst <$> fakeOvers)
let fakeProblem = [ (fromJust (lookup src srcMap), pat) | (src, pat) <- problem ]
fakeEnv <- localFC abstFC $ solve ?my fakeProblem >>= (solToEnv . snd)
case ?my of
Braty -> do
constraints <- constraintsFromEnv (concat . M.elems $ fakeEnv)
traverse_ fulbournConstraint constraints
_ -> pure ()
pure (fakeEnv, fakeAcc)
localEnv fakeEnv $ do
(_, fakeUnders, [], _) <- anext "lambda_fake_target" Hypo fakeAcc outs R0
Expand Down Expand Up @@ -387,16 +396,19 @@ check' (Var x) ((), ()) = (, ((), ())) . ((),) <$> case ?my of
Kerny -> req (KLup x) >>= \case
Just (p, ty) -> pure [(p, ty)]
Nothing -> err $ KVarNotFound (show x)
check' (Arith op l r) ((), u@(hungry, ty):unders) = case (?my, ty) of
(Braty, ty) -> do
ty <- evalBinder Braty ty
case ty of
Right TNat -> check_arith TNat
Right TInt -> check_arith TInt
Right TFloat -> check_arith TFloat
_ -> err . ArithNotExpected $ show u
check' (Arith op l r) ((), (hungry, ty):unders) = case (?my, ty) of
(Braty, ty) -> checkNumTy ty
(Kerny, _) -> err ArithInKernel
where
checkNumTy :: BinderType Brat -> Checking (SynConnectors m d k, ChkConnectors m d k)
checkNumTy (Right ty) | ty `elem` [TNat, TInt, TFloat] = check_arith ty
-- Why don't we allow Left Nat??
checkNumTy (Right ty@(VApp (VPar e) B0)) = do
mkYield (NeedToKnow e) "WaitingForArithHope" (S.singleton e)
ty <- eval S0 ty
checkNumTy (Right ty)
checkNumTy _ = err $ ArithNotExpected (show ty)

check_arith ty = let ?my = Braty in do
let inRo = RPr ("left", ty) $ RPr ("right", ty) R0
let outRo = RPr ("out", ty) R0
Expand Down Expand Up @@ -707,10 +719,39 @@ check' (Hope ident) ((), (tgt@(NamedPort bang _), ty):unders) = case (?my, ty) o
defineSrc' "check hope (src)" dangling (endVal k (toEnd hungry))
req (ANewDynamic (end hungry) fc)
pure (((), ()), ((), unders))
(Braty, Right _ty) -> typeErr "Can only infer kinded things with !"
(Braty, Right (VEqn lhs rhs)) -> do
mkFork "SolveHopedConstraint" $ solveConstraint ident tgt (lhs, rhs)
pure (((), ()), ((), unders))
(Braty, Right _ty) -> typeErr "Can only infer kinded things or equations with !"
(Kerny, _) -> typeErr "Won't infer kernel typed !"
check' tm _ = error $ "check' " ++ show tm

solveConstraint :: String -> Tgt -> (NumSum (VVar Z), NumSum (VVar Z))
-> Checking ()
solveConstraint ident tgt (lhs,rhs) = do
CtxEnv _ locals <- req AskVEnv
constraints <- constraintsFromEnv (concat (M.elems locals))
traceM ("Got:\n> " ++ show constraints)
lhs <- numSumUpdate lhs
rhs <- numSumUpdate rhs
let eqSimp@(lhsSimp, rhsSimp) = simplify (lhs, rhs)
traceM ("Want:\n> " ++ show eqSimp)
if eqSimp `elem` ((NumSum 0 [], NumSum 0 []):constraints)
then defineTgt' ident tgt (VEqn lhsSimp rhsSimp)
else do
mkFork "" $ fulbournConstraint eqSimp
mkYield (WaitingForConstraint (show eqSimp)) ident (S.fromList $ depEnds eqSimp)
solveConstraint ident tgt eqSimp


constraintsFromEnv :: [(a, BinderType Brat)] -> Checking [(NumSum (VVar Z), NumSum (VVar Z))]
constraintsFromEnv [] = pure []
constraintsFromEnv ((_, Right (VEqn lhs rhs)):overs) = do
lhs <- numSumUpdate lhs
rhs <- numSumUpdate rhs
let eqn = simplify (lhs, rhs)
(eqn:) <$> constraintsFromEnv overs
constraintsFromEnv (_:xs) = constraintsFromEnv xs

-- Clauses from either function definitions or case statements, as we get
-- them from the elaborator
Expand Down Expand Up @@ -744,7 +785,13 @@ checkClause my fnName cty clause = modily my $ do
problem <- argProblems (fst <$> overs) (unWC $ lhs clause) []
(tests, sol) <- localFC (fcOf (lhs clause)) $ solve my problem
(sol, defs) :: ([(String, (Src, BinderType m))], [((String, TypeKind), Val Z)]) <- case my of
Braty -> postProcessSolAndOuts sol unders
Braty -> do
(sol, defs) <- postProcessSolAndOuts sol unders
constraints <- constraintsFromEnv (second snd <$> sol)
traverse fulbournConstraint constraints
--traceM ("We've got (checkClause):\n " ++ show constraints)
pure (sol, defs)

Kerny -> pure (sol, [])
-- The solution gives us the variables bound by the patterns.
-- We turn them into a row
Expand Down Expand Up @@ -789,7 +836,8 @@ checkClause my fnName cty clause = modily my $ do
(Some stk) <><< (x:xs) = Some (stk :<< x) <><< xs

-- Process a solution, finding Ends that support the solved types, and return a list of definitions for substituting later on
postProcessSolAndOuts :: [(String, (Src, BinderType Brat))] -> [(Tgt, BinderType Brat)] -> Checking ([(String, (Src, BinderType Brat))], [((String, TypeKind), Val Z)])
postProcessSolAndOuts :: [(String, (Src, BinderType Brat))] -> [(Tgt, BinderType Brat)]
-> Checking ([(String, (Src, BinderType Brat))], [((String, TypeKind), Val Z)])
postProcessSolAndOuts sol outputs = worker B0 sol
where
worker :: Bwd (String, (Src, BinderType Brat)) -> [(String, (Src, BinderType Brat))] -> Checking ([(String, (Src, BinderType Brat))], [((String, TypeKind), Val Z)])
Expand All @@ -805,9 +853,6 @@ checkClause my fnName cty clause = modily my $ do
zx <- pure $ foldl (\sol srcAndTy -> insert ("$" ++ show (end (fst srcAndTy)), srcAndTy) sol) zx srcAndTys
(sol, defs) <- worker (zx {-:< entry-}) sol
pure ({-(patVar, (src, Left k)):-}sol, ((patVar, k), def):defs)
-- Pat vars beginning with '_' aren't in scope, we can ignore them
-- (but if they're kinded they might come up later as the dependency of something else)
worker zx (('_':_, _):sol) = worker zx sol
worker zx (entry@(_patVar, (_src, Right ty)):sol) = do
trackM ("processSol (typed): " ++ show entry)
ty <- eval S0 ty
Expand Down Expand Up @@ -1043,13 +1088,92 @@ kindCheck ((hungry, Nat):unders) (Con c arg)
defineTgt' "kind8" hungry v
pure ([v], unders)

kindCheck ((hungry, Star []):unders) (Eqn (WC lwc lhs) (WC rwc rhs)) = do
-- Should we make a new `NodeType` for this?
(_, [(lunder,_),(runder,_)], [(dangling,_)], _) <- next "Eq" Hypo (S0, Some (Zy :* S0))
(REx ("lhs", Nat) (REx ("rhs", Nat) R0))
(REx ("out", Star []) R0)
lns <- localFC lwc $ kindCheckNumSum lunder lhs
rns <- localFC rwc $ kindCheckNumSum runder rhs
wire (dangling, TUnit, hungry)
pure ([VEqn lns rns], unders)
kindCheck ((_, k):_) tm = typeErr $ "Expected " ++ show tm ++ " to have kind " ++ show k


-- N.B. We're not really doing any defining that would be useful for the
-- typechecker yet. The obvious defining isn't possible because NumSum is not a
-- `Val`.
kindCheckNumSum :: Tgt -- Nat kinded tgt to wire numsum to
-> Term Chk Noun -- The term to turn into a numsum
-> Checking (NumSum (VVar Z))
kindCheckNumSum hungry (Arith op (WC lwc lhs) (WC rwc rhs)) = do
(_, [(lunder,_),(runder,_)], [(dangling, _)], _) <- next (show op ++ "NS") (ArithNode op)
(S0, Some (Zy :* S0))
(REx ("lhs", Nat) (REx ("rhs", Nat) R0))
(REx ("out", Nat) R0)

ns <- case op of
Add -> do
lns <- kindCheckNumSum lunder lhs
rns <- kindCheckNumSum runder rhs
pure (lns <> rns)
Mul -> do
lns <- kindCheckNumSum lunder lhs
rns <- kindCheckNumSum runder rhs
case (lns, rns) of
(NumSum c [], _) -> let ns = multNumSum rns c in ns <$ wire (dangling, TNat, hungry)
(_, NumSum c []) -> let ns = multNumSum lns c in ns <$ wire (dangling, TNat, hungry)
_ -> localFC eqFC $ typeErr "Constraint too complicated: must be between sums"
Sub -> do
lns <- kindCheckNumSum lunder lhs
rns <- kindCheckNumSum runder rhs
case numSumSub lns rns of
Just ns -> ns <$ wire (dangling, TNat, hungry)
Nothing -> localFC rwc $ typeErr "Subtraction too complicated"
Pow -> do
lns <- kindCheckNumSum lunder lhs
rns <- kindCheckNumSum runder rhs
case (lns, rns) of
(NumSum n [], rns)
| Just k <- log2 n, Just nv <- sumToVal rns -> pure (nv_to_sum (powN k nv))
_ -> localFC eqFC $ typeErr "Power too confusing"

Div -> localFC eqFC $ typeErr "Won't handle division in equations"
wire (dangling, TNat, hungry)
pure ns
where
eqFC = spanFC lwc rwc

-- Take 2^n
powN :: Integer -> NumVal v -> NumVal v
powN 0 nv = nv
powN k nv = powN (k - 1) (nPlus 1 (nFull nv))

numSumSub :: NumSum (VVar Z) -> NumSum (VVar Z) -> Maybe (NumSum (VVar Z))
numSumSub (NumSum c vs) (NumSum d ws) | c >= d = NumSum (c-d) <$> aux vs ws
where
-- blah blah O(n^2)
aux :: [(Monotone (VVar Z), Integer)] -> [(Monotone (VVar Z), Integer)]
-> Maybe [(Monotone (VVar Z), Integer)]
aux monos [] = Just monos
aux monos ((v, n):vs) = case [ m | (w, m) <- monos, w == v ] of
[m] | m >= n -> ((v, m - n):) <$> aux monos vs
[] -> Nothing

sumToVal :: NumSum v -> Maybe (NumVal v)
sumToVal (NumSum up [(n, k)]) | Just l <- log2 k = Just $ nPlus up (n2PowTimes l (numValue n))
sumToVal _ = Nothing

kindCheckNumSum under tm = do
([val], []) <- kindCheck [(under, Nat)] tm
case val of
VNum nv -> let ns = nv_to_sum nv in pure ns -- TODO: Wiring
x -> error $ "Didn't expect: " ++ show x

-- Checks the kinds of the types in a dependent row
kindCheckRow :: Modey m
-> String -- for node name
-> [(PortName, ThunkRowType m)] -- The row to process
-> [TypeRowElem TermConstraint (ThunkRowType m)] -- The row to process
-> Checking (Some (Ro m Z))
kindCheckRow my name r = do
name <- req $ Fresh $ "__kcr_" ++ name
Expand All @@ -1060,7 +1184,7 @@ kindCheckRow my name r = do
-- evaluation of the type of an Id node passing through such values
kindCheckAnnotation :: Modey m
-> String -- for node name
-> [(PortName, ThunkRowType m)]
-> [TypeRowElem TermConstraint (ThunkRowType m)]
-> Checking (CTy m Z)
kindCheckAnnotation my name outs = do
trackM "kca"
Expand All @@ -1080,17 +1204,19 @@ kindCheckRow' :: forall m n
-> Endz n -- kind outports so far
-> VEnv -- from string variable names to VPar's
-> (Name, Int) -- node name and next free input (under to 'kindCheck' a type)
-> [(PortName, ThunkRowType m)]
-> [TypeRowElem TermConstraint (ThunkRowType m)]
-> Checking (Int, VEnv, Some (Endz :* Ro m n))
kindCheckRow' _ ez env (_,i) [] = pure (i, env, Some (ez :* R0))
kindCheckRow' Braty (ny :* s) env (name,i) ((p, Left k):rest) = do -- s is Stack Z n

kindCheckRow' my nys env (name, i) ((Anon ty):rest) = kindCheckRow' my nys env (name, i) ((Named ('_':show i) ty):rest)
kindCheckRow' Braty (ny :* s) env (name,i) ((Named p (Left k)):rest) = do -- s is Stack Z n
let dangling = Ex name (ny2int ny)
req (Declare (ExEnd dangling) Braty (Left k) Definable) -- assume none are SkolemConst??
env <- pure $ M.insert (plain p) [(NamedPort dangling p, Left k)] env
(i, env, ser) <- kindCheckRow' Braty (Sy ny :* (s :<< ExEnd dangling)) env (name, i) rest
case ser of
Some (s_m :* ro) -> pure (i, env, Some (s_m :* REx (p,k) ro))
kindCheckRow' my ez@(ny :* s) env (name, i) ((p, bty):rest) = case (my, bty) of
kindCheckRow' my ez@(ny :* s) env (name, i) ((Named p bty):rest) = case (my, bty) of
(Braty, Right ty) -> helper ty (Star [])
(Kerny, ty) -> helper ty (Dollar [])

Expand Down Expand Up @@ -1229,6 +1355,9 @@ abstractPattern my (dangling, bty) pat@(PCon pcon abst) = case (my, bty) of
,"with type"
,show ty])

-- N.B. We desperately want to delete these functions and have Let binding use
-- the normal SolvePatterns logic, so we haven't bothered to solve equations
-- from the CArgs here.
abstractCon :: Modey m
-> (QualName -> QualName -> Checking (CtorArgs m))
-> (QualName, [Val Z])
Expand Down
Loading
Loading