diff --git a/.github/workflows/web-demos.yml b/.github/workflows/web-demos.yml index e7b9c6f8..6979b250 100644 --- a/.github/workflows/web-demos.yml +++ b/.github/workflows/web-demos.yml @@ -13,99 +13,98 @@ concurrency: group: web-demos-${{ github.event_name }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true -# jobs: -# build-and-deploy: -# runs-on: ubuntu-latest -# env: -# CARGO_TARGET_DIR: ${{ github.workspace }}/target -# NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} -# NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} +jobs: + # build-and-deploy: + # runs-on: ubuntu-latest + # env: + # CARGO_TARGET_DIR: ${{ github.workspace }}/target + # NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} + # NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID }} -# steps: -# - name: Checkout ⬇️ -# uses: actions/checkout@v6 + # steps: + # - name: Checkout ⬇️ + # uses: actions/checkout@v6 -# - name: Install Nix ❄️ -# uses: cachix/install-nix-action@v31 + # - name: Install Nix ❄️ + # uses: cachix/install-nix-action@v31 -# - name: Set up Cachix ♻️ -# if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository -# uses: cachix/cachix-action@v17 -# with: -# name: coln -# authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} + # - name: Set up Cachix ♻️ + # if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository + # uses: cachix/cachix-action@v17 + # with: + # name: coln + # authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} -# - name: Restore build caches -# uses: actions/cache@v4 -# with: -# path: | -# .pnpm-store -# ~/.npm -# ~/.cargo/registry -# ~/.cargo/git -# ~/.ghc-wasm/.cabal -# target -# dist-newstyle -# key: web-demos-${{ runner.os }}-${{ hashFiles('flake.lock', 'Cargo.lock', 'cabal.project', 'packages/**/*.cabal', 'packages/coln-js-runtime/package-lock.json', 'examples/sync-demo/pnpm-lock.yaml') }} -# restore-keys: | -# web-demos-${{ runner.os }}- + # - name: Restore build caches + # uses: actions/cache@v4 + # with: + # path: | + # .pnpm-store + # ~/.npm + # ~/.cargo/registry + # ~/.cargo/git + # ~/.ghc-wasm/.cabal + # target + # dist-newstyle + # key: web-demos-${{ runner.os }}-${{ hashFiles('flake.lock', 'Cargo.lock', 'cabal.project', 'packages/**/*.cabal', 'packages/coln-js-runtime/package-lock.json', 'examples/sync-demo/pnpm-lock.yaml') }} + # restore-keys: | + # web-demos-${{ runner.os }}- -# - name: Build sync demo -# run: nix run --accept-flake-config .#sync-demo -- "$GITHUB_WORKSPACE" -# env: -# VITE_BASE: /sync/ + # - name: Build sync demo + # run: nix run --accept-flake-config .#sync-demo -- "$GITHUB_WORKSPACE" + # env: + # VITE_BASE: /sync/ -# - name: Build web compiler -# run: | -# nix develop --accept-flake-config --command wasm32-wasi-cabal update 'hackage.haskell.org,2026-07-15T17:07:49Z' -# nix develop --accept-flake-config --command just examples/build-web-compiler + # - name: Build web compiler + # run: | + # nix develop --accept-flake-config --command wasm32-wasi-cabal update 'hackage.haskell.org,2026-07-15T17:07:49Z' + # nix develop --accept-flake-config --command just examples/build-web-compiler -# - name: Assemble deploy directory -# run: | -# cp examples/index.html examples/style.css _build/web/ -# cp -r examples/sync-demo/dist _build/web/sync + # - name: Assemble deploy directory + # run: | + # cp examples/index.html examples/style.css _build/web/ + # cp -r examples/sync-demo/dist _build/web/sync -# - name: Deploy PR preview to Netlify -# id: deploy-preview -# if: github.event_name == 'pull_request' && env.NETLIFY_AUTH_TOKEN != '' && env.NETLIFY_SITE_ID != '' -# run: | -# npx --yes netlify-cli@latest deploy \ -# --auth "$NETLIFY_AUTH_TOKEN" \ -# --site "$NETLIFY_SITE_ID" \ -# --dir _build/web \ -# --no-build \ -# --alias "pr-${{ github.event.pull_request.number }}" \ -# --message "PR #${{ github.event.pull_request.number }} web demos" \ -# --json > netlify-deploy.json + # - name: Deploy PR preview to Netlify + # id: deploy-preview + # if: github.event_name == 'pull_request' && env.NETLIFY_AUTH_TOKEN != '' && env.NETLIFY_SITE_ID != '' + # run: | + # npx --yes netlify-cli@latest deploy \ + # --auth "$NETLIFY_AUTH_TOKEN" \ + # --site "$NETLIFY_SITE_ID" \ + # --dir _build/web \ + # --no-build \ + # --alias "pr-${{ github.event.pull_request.number }}" \ + # --message "PR #${{ github.event.pull_request.number }} web demos" \ + # --json > netlify-deploy.json -# cat netlify-deploy.json -# deploy_url=$(node -e "const d = require('./netlify-deploy.json'); console.log(d.deploy_ssl_url || d.ssl_url || d.deploy_url || d.url)") -# echo "deploy-url=$deploy_url" >> "$GITHUB_OUTPUT" + # cat netlify-deploy.json + # deploy_url=$(node -e "const d = require('./netlify-deploy.json'); console.log(d.deploy_ssl_url || d.ssl_url || d.deploy_url || d.url)") + # echo "deploy-url=$deploy_url" >> "$GITHUB_OUTPUT" -# - name: Comment with deploy preview URL -# if: github.event_name == 'pull_request' && steps.deploy-preview.outputs.deploy-url != '' -# uses: actions/github-script@v8 -# with: -# script: | -# const marker = '' -# const body = `${marker}\nWeb demo preview: ${{ steps.deploy-preview.outputs.deploy-url }}` -# const { owner, repo } = context.repo -# const issue_number = context.issue.number -# const comments = await github.rest.issues.listComments({ owner, repo, issue_number, per_page: 100 }) -# const existing = comments.data.find(comment => comment.body?.includes(marker)) -# if (existing) { -# await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body }) -# } else { -# await github.rest.issues.createComment({ owner, repo, issue_number, body }) -# } - -# - name: Deploy main to Netlify production -# if: github.event_name == 'push' && env.NETLIFY_AUTH_TOKEN != '' && env.NETLIFY_SITE_ID != '' -# run: | -# npx --yes netlify-cli@latest deploy \ -# --auth "$NETLIFY_AUTH_TOKEN" \ -# --site "$NETLIFY_SITE_ID" \ -# --dir _build/web \ -# --no-build \ -# --prod \ -# --message "web demos ${{ github.sha }}" + # - name: Comment with deploy preview URL + # if: github.event_name == 'pull_request' && steps.deploy-preview.outputs.deploy-url != '' + # uses: actions/github-script@v8 + # with: + # script: | + # const marker = '' + # const body = `${marker}\nWeb demo preview: ${{ steps.deploy-preview.outputs.deploy-url }}` + # const { owner, repo } = context.repo + # const issue_number = context.issue.number + # const comments = await github.rest.issues.listComments({ owner, repo, issue_number, per_page: 100 }) + # const existing = comments.data.find(comment => comment.body?.includes(marker)) + # if (existing) { + # await github.rest.issues.updateComment({ owner, repo, comment_id: existing.id, body }) + # } else { + # await github.rest.issues.createComment({ owner, repo, issue_number, body }) + # } + # - name: Deploy main to Netlify production + # if: github.event_name == 'push' && env.NETLIFY_AUTH_TOKEN != '' && env.NETLIFY_SITE_ID != '' + # run: | + # npx --yes netlify-cli@latest deploy \ + # --auth "$NETLIFY_AUTH_TOKEN" \ + # --site "$NETLIFY_SITE_ID" \ + # --dir _build/web \ + # --no-build \ + # --prod \ + # --message "web demos ${{ github.sha }}" diff --git a/manual/templates/plain.tree b/manual/templates/plain.tree new file mode 100644 index 00000000..e69de29b diff --git a/manual/trees/0001.tree b/manual/trees/0001.tree index 38184706..d6d04343 100644 --- a/manual/trees/0001.tree +++ b/manual/trees/0001.tree @@ -2,9 +2,11 @@ \p{Coln is a database with an expressive language for schemas, queries, and migrations. This document forms the manual for Coln.} -\transclude{002H} -\transclude{0002} -\transclude{000K} -\transclude{000L} -\transclude{000M} -\transclude{0003} +\ol{ + \li{[[002H]]} + \li{[[0002]]} + \li{[[000K]]} + \li{[[000L]]} + \li{[[000M]]} + \li{[[0003]]} +} diff --git a/manual/trees/0002.tree b/manual/trees/0002.tree index 3e4ac337..31903d18 100644 --- a/manual/trees/0002.tree +++ b/manual/trees/0002.tree @@ -72,8 +72,4 @@ \transclude{000B} -\subtree[000I]{ - \title{Organization} - - \p{} -} +\transclude{000I} diff --git a/manual/trees/000I.tree b/manual/trees/000I.tree new file mode 100644 index 00000000..082e2790 --- /dev/null +++ b/manual/trees/000I.tree @@ -0,0 +1,3 @@ +\title{Organization} + +\p{} diff --git a/manual/trees/002K.tree b/manual/trees/002K.tree new file mode 100644 index 00000000..f54be495 --- /dev/null +++ b/manual/trees/002K.tree @@ -0,0 +1 @@ +\title{Developer documentation} diff --git a/packages/coln-compiler/coln-compiler.cabal b/packages/coln-compiler/coln-compiler.cabal index d2817239..763c7318 100644 --- a/packages/coln-compiler/coln-compiler.cabal +++ b/packages/coln-compiler/coln-compiler.cabal @@ -30,6 +30,7 @@ library Coln.Core.Syntax Coln.Core.Value Coln.Diagnostics + Coln.Elaborator.Coercion Coln.Elaborator.Debug Coln.Elaborator.Diagnostics Coln.Elaborator.Environment @@ -37,12 +38,16 @@ library Coln.Elaborator.Rules.Builtin Coln.Elaborator.Rules.Equality Coln.Elaborator.Rules.Function + Coln.Elaborator.Rules.Initial + Coln.Elaborator.Rules.Polarity Coln.Elaborator.Rules.Record Coln.Elaborator.Rules.Universe Coln.Elaborator.Rules.Variable Coln.Frontend.Diagnostics Coln.Frontend.Notation Coln.Frontend.Parser + Coln.Frontend.Parser.Expr + Coln.Frontend.Parser.Top Coln.Report hs-source-dirs: src diff --git a/packages/coln-compiler/src/Coln/Backend/Lower.hs b/packages/coln-compiler/src/Coln/Backend/Lower.hs index 4dceb3fa..df1ebdfd 100644 --- a/packages/coln-compiler/src/Coln/Backend/Lower.hs +++ b/packages/coln-compiler/src/Coln/Backend/Lower.hs @@ -73,6 +73,7 @@ instance Lower (V.El N) Term where lower :: CtxLen -> V.El N -> Term lower n = \case V.Neu ne -> lower n ne + V.InitNeu _ -> panic "can't lower init yet" V.Code _ -> panic "non set-level term" V.Lam _ _ -> panic "non set-level term" V.Cons ds -> Cons (lower n <$> ds) @@ -99,6 +100,7 @@ separate n = \case let (shapes, props) = unzip $ go rt.capture (toList rt.fieldTypes) Ty (Tuple (withHead rt.fieldTypes shapes)) (And (withHead rt.fieldTypes props)) Nothing -> panic "lowering neutral type" + V.InitDecode _ -> panic "can't lower init yet" V.Function _ -> panic "lowering non-set-level type: Function" V.Eq et -> \_ -> Ty Unit (Equal (lower n et.lhs) (lower n et.rhs)) V.BuiltinTy t -> \_ -> Ty (BuiltinTy t) PTrue diff --git a/packages/coln-compiler/src/Coln/Backend/TypeScript/Generate.hs b/packages/coln-compiler/src/Coln/Backend/TypeScript/Generate.hs index 3c86fcb5..ab2a4451 100644 --- a/packages/coln-compiler/src/Coln/Backend/TypeScript/Generate.hs +++ b/packages/coln-compiler/src/Coln/Backend/TypeScript/Generate.hs @@ -117,6 +117,7 @@ genEntryModule imports a ev = go 0 a ev case V.ebind V.decode ev' of V.Become a -> TS.DTypeDef $ genTypeDef access n a V.Describe a -> TS.DInterface $ genInterface access n a + V.BecomeWith _ -> panic "can't lower becomewith yet" Just $ TS.Module imports (TS.Exported <$> definitions) go n (V.Function ft) ev' = do let v = V.local (FId n) ft.dom @@ -172,6 +173,7 @@ argName _ (V.CloConst _) = panic "closures from the layout process should have a genEl :: Access -> TSCtxShape -> V.El N -> TS.El genEl access cs = \case V.Neu n -> genSp cs n.spine $ genHead access cs n.head + V.InitNeu _ -> panic "can't lower init yet" V.Code a -> genTyVal access cs a V.Lam dom clo -> do let v = V.local (FId cs.len) dom diff --git a/packages/coln-compiler/src/Coln/Core/Conversion.hs b/packages/coln-compiler/src/Coln/Core/Conversion.hs index 5ca80c0c..a7184b70 100644 --- a/packages/coln-compiler/src/Coln/Core/Conversion.hs +++ b/packages/coln-compiler/src/Coln/Core/Conversion.hs @@ -62,6 +62,9 @@ instance DefEq (V.Ty N) where V.Decode n -> case a' of V.Decode n' -> defEq cs n n' _ -> throwUnequalTys cs a a' Nothing + V.InitDecode n -> case a' of + V.InitDecode n' -> defEq cs n n' + _ -> throwUnequalTys cs a a' Nothing V.Function f -> case a' of V.Function f' -> do unless (f.variant == f'.variant) $ @@ -123,6 +126,9 @@ instance DefEq V.DecodedNeutral where instance DefEq V.Neutral where defEq cs n n' = defEq cs (V.toBare n) (V.toBare n') +instance DefEq V.InitNeutral where + defEq cs n n' = defEq cs (V.fullNeu n) (V.fullNeu n') + canon :: V.El N -> V.El N canon v@(V.Neu n) = case V.behavior n.ty of V.LikeRecord _ -> V.Cons (V.unwrap n.expansion) @@ -137,6 +143,9 @@ instance DefEq (V.El N) where V.Neu n -> case canon v' of V.Neu n' -> defEq cs n n' _ -> throwUnequalEls cs v v' Nothing + V.InitNeu n -> case canon v' of + V.InitNeu n' -> defEq cs n n' + _ -> throwUnequalEls cs v v' Nothing V.Code a -> case canon v' of V.Code a' -> defEq cs a a' _ -> throwUnequalEls cs v v' Nothing diff --git a/packages/coln-compiler/src/Coln/Core/Evaluation.hs b/packages/coln-compiler/src/Coln/Core/Evaluation.hs index 4ee38f13..d5bdab05 100644 --- a/packages/coln-compiler/src/Coln/Core/Evaluation.hs +++ b/packages/coln-compiler/src/Coln/Core/Evaluation.hs @@ -43,6 +43,9 @@ instance Compile S.El V.El where S.Proj t x -> do let k = compile t \vs -> V.proj (k vs) x + S.Init t -> do + let k = compile t + \vs -> V.BecomeWith $ \n -> V.InitNeu (V.InitNeutral n (k vs) V.Id) S.Lit l -> \_ -> V.Lit l S.Is t -> do let k = compile t diff --git a/packages/coln-compiler/src/Coln/Core/Globals.hs b/packages/coln-compiler/src/Coln/Core/Globals.hs index e6946b05..907d739a 100644 --- a/packages/coln-compiler/src/Coln/Core/Globals.hs +++ b/packages/coln-compiler/src/Coln/Core/Globals.hs @@ -17,6 +17,7 @@ data GlobalEntry = GlobalEntry { syn :: S.El D , val :: V.El N , ty :: V.Ty N + , mode :: Mode } data Globals = Globals diff --git a/packages/coln-compiler/src/Coln/Core/Layout.hs b/packages/coln-compiler/src/Coln/Core/Layout.hs index 387630db..e43ffcb3 100644 --- a/packages/coln-compiler/src/Coln/Core/Layout.hs +++ b/packages/coln-compiler/src/Coln/Core/Layout.hs @@ -71,7 +71,7 @@ layout p sc a let a = V.EltOf (TableName sc.realm p) (fromList $ zip (toList sc.names) (toList sc.bound)) (gt, M.code (M.fromVTy sc.len a)) V.NoRules -> panic "cannot layout type with no rules" - V.LikeBuiltinTy _; V.LikeU _ -> panic "non-theory type" + V.LikeBuiltinTy _; V.LikeU _; V.LikeInductive _ -> panic "non-theory type" | (levelOf a).mlevel == Set = do let gt = Leaf (Fun (toList sc.names) (toList sc.ctx) (readb sc.len a)) let v = V.tableLookup (TableName sc.realm p) (fromList $ zip (toList sc.names) (toList sc.bound)) a diff --git a/packages/coln-compiler/src/Coln/Core/Memoed.hs b/packages/coln-compiler/src/Coln/Core/Memoed.hs index 7da6002e..a492e0e7 100644 --- a/packages/coln-compiler/src/Coln/Core/Memoed.hs +++ b/packages/coln-compiler/src/Coln/Core/Memoed.hs @@ -30,6 +30,7 @@ class Core el ty | el -> ty, ty -> el where lam :: (V.HasEvaluation c) => V.Locals -> ty N -> S.Abs el c -> el c cons :: (V.HasEvaluation c) => Dict (el c) -> el c proj :: el N -> Name -> el N + init :: ty N -> el D lit :: Literal -> el N is :: el N -> el D univ :: Universe -> ty N @@ -55,6 +56,8 @@ instance Core El Ty where (V.epure $ V.Lam dom.val (V.CloConst body.val)) cons d = M (S.Cons $ (.stx) <$> d) (V.epure $ V.Cons $ (.val) <$> d) proj x f = M (S.Proj x.stx f) (V.proj x.val f) + init a = + M (S.Init a.stx) (V.BecomeWith $ \n -> V.InitNeu (V.InitNeutral n a.val V.Id)) lit l = M (S.Lit l) (V.Lit l) is x = M (S.Is x.stx) (V.Become x.val) univ u = M (S.U u) (V.U u) @@ -90,11 +93,13 @@ instance (V.HasEvaluation c) => LevelOf (Ty c) where SDescriptive -> case ty.val of V.Describe ty' -> levelOf ty' V.Become ty' -> levelOf ty' + -- This is kind of a hack, but shouldn't appear in practice in any case + V.BecomeWith f -> levelOf (f $ V.BareNeutral (V.LocalVar (FId 0)) V.Id) instance Readback (Memoed a b c) (a c) where readb _ m = m.stx -mkGlobal :: Name -> V.Ty N -> El D -> GlobalEntry -mkGlobal n ty x = do +mkGlobal :: Name -> V.Ty N -> El D -> Mode -> GlobalEntry +mkGlobal n ty x m = do let neu = V.reflect (V.GlobalVar n neu) V.Id ty (Just x.val) - GlobalEntry x.stx neu ty + GlobalEntry x.stx neu ty m diff --git a/packages/coln-compiler/src/Coln/Core/Params.hs b/packages/coln-compiler/src/Coln/Core/Params.hs index 93913b81..3a5655a9 100644 --- a/packages/coln-compiler/src/Coln/Core/Params.hs +++ b/packages/coln-compiler/src/Coln/Core/Params.hs @@ -109,7 +109,11 @@ functionMLevelFor v1 v2 = case (v1, v2) of (Theory, _) -> pure TheoryTop (Top, _) -> Nothing -data FunctionVariant = FunctionVariant {mlevel :: FunctionVariantMLevel, hlevel :: HLevel} +data FunctionVariant = FunctionVariant + { mlevel :: FunctionVariantMLevel + , hlevel :: HLevel + , domainMode :: Mode + } deriving (Eq, Show) instance Pretty FunctionVariant where @@ -183,3 +187,12 @@ data TableName = TableName {realm :: RealmId, path :: Path} instance DPretty TableName where dpretty tn = concatWith (surround dot) (dpretty <$> toList tn.path) + +-- Mode +-------------------------------------------------------------------------------- + +data Mode = Inductive | Conjunctive + deriving (Show, Eq, Ord) + +instance DPretty Mode where + dpretty = pretty . show diff --git a/packages/coln-compiler/src/Coln/Core/Print.hs b/packages/coln-compiler/src/Coln/Core/Print.hs index 365df236..dbf6f34a 100644 --- a/packages/coln-compiler/src/Coln/Core/Print.hs +++ b/packages/coln-compiler/src/Coln/Core/Print.hs @@ -55,6 +55,7 @@ instance ToNotation (El e) where N.Tuple [field y t | (y, t) <- toList d] () where field y t = N.Infix (N.Ident y ()) (N.Keyword ":=" ()) (toNotation xs t) + Init t -> N.Juxt (N.Keyword "init" ()) (toNotation xs t) Lit (LitInt i) -> N.Int i () Lit (LitString s) -> N.String s () Is t -> toNotation xs t -- invisible @@ -102,6 +103,7 @@ instance ToNotation TypeBehavior where LikeFunction ft -> toNotation xs (Function ft) LikeRecord rt -> toNotation xs (Record rt) LikeBuiltinTy bt -> toNotation xs (BuiltinTy bt) + LikeInductive t -> toNotation xs t NoRules -> N.Keyword "NoRules" () toNotationTele :: [Name] -> [Ty N] -> [N.Ntn0] diff --git a/packages/coln-compiler/src/Coln/Core/Readback.hs b/packages/coln-compiler/src/Coln/Core/Readback.hs index 42953090..2b720af5 100644 --- a/packages/coln-compiler/src/Coln/Core/Readback.hs +++ b/packages/coln-compiler/src/Coln/Core/Readback.hs @@ -36,6 +36,8 @@ instance Readback (V.Description V.El) (S.El D) where readb n = \case V.Describe v -> readb n v V.Become v -> S.Is (readb n v) + V.BecomeWith f -> + S.Is (readb (n + 1) (f (V.BareNeutral (V.LocalVar (FId n)) V.Id))) readbClo :: (Readback (V.Evaluation a c) (b c)) => CtxLen -> V.Ty N -> V.Clo a c -> S.Abs b c readbClo n dom = \case @@ -45,6 +47,7 @@ readbClo n dom = \case instance (V.HasEvaluation c) => Readback (V.El c) (S.El c) where readb n = \case V.Neu ne -> readb n ne.spine $ readb n ne.head + V.InitNeu ne -> readb n ne.spine $ readb n ne.name V.Code a -> S.Code (readb n a) V.Lam dom body -> S.Lam (readb n dom) $ case V.scase @c of SNominative -> readbClo n dom body @@ -92,6 +95,7 @@ instance (V.HasEvaluation c) => Readback (V.Ty c) (S.Ty c) where readb n = \case V.U u -> S.U u V.Decode ne -> S.Decode $ readb n ne.spine $ readb n ne.head + V.InitDecode ne -> S.Decode $ readb n ne.spine $ readb n ne.name V.Function f -> S.Function $ readb n f V.Record r -> S.Record $ readb n r V.Eq eq -> S.Eq $ readb n eq @@ -103,5 +107,6 @@ instance Readback V.TypeBehavior S.TypeBehavior where V.LikeU u -> S.LikeU u V.LikeRecord rt -> S.LikeRecord $ readb n rt V.LikeFunction ft -> S.LikeFunction $ readb n ft + V.LikeInductive ne -> S.LikeInductive $ readb n ne.spine $ readb n ne.name V.LikeBuiltinTy bt -> S.LikeBuiltinTy bt V.NoRules -> S.NoRules diff --git a/packages/coln-compiler/src/Coln/Core/Syntax.hs b/packages/coln-compiler/src/Coln/Core/Syntax.hs index e8dc774e..813ceb0b 100644 --- a/packages/coln-compiler/src/Coln/Core/Syntax.hs +++ b/packages/coln-compiler/src/Coln/Core/Syntax.hs @@ -23,6 +23,7 @@ data El :: Case -> Type where App :: El N -> El N -> El N Cons :: Dict (El c) -> El c Proj :: El N -> Name -> El N + Init :: Ty N -> El D Lit :: Literal -> El N Is :: El N -> El D Lookup :: TableName -> Dict (El N) -> Ty N -> El N @@ -58,5 +59,6 @@ data TypeBehavior = LikeU Universe | LikeFunction (FunctionType Ty) | LikeRecord (RecordType Ty) + | LikeInductive (El N) | LikeBuiltinTy BuiltinTy | NoRules diff --git a/packages/coln-compiler/src/Coln/Core/Value.hs b/packages/coln-compiler/src/Coln/Core/Value.hs index 5fc0ffee..d08c76ae 100644 --- a/packages/coln-compiler/src/Coln/Core/Value.hs +++ b/packages/coln-compiler/src/Coln/Core/Value.hs @@ -36,6 +36,7 @@ type family Evaluation (f :: Case -> Type) (c :: Case) = r | r -> c f where data Description :: (Case -> Type) -> Type where Describe :: f D -> Description f Become :: f N -> Description f + BecomeWith :: (BareNeutral -> f N) -> Description f class HasEvaluation (c :: Case) where epure :: a c -> Evaluation a c @@ -53,8 +54,10 @@ instance HasEvaluation D where epure = Describe emap f (Describe x) = Describe (f x) emap f (Become x) = Become (f x) + emap f (BecomeWith g) = BecomeWith (f . g) ebind f (Describe x) = f x ebind f (Become x) = Become (f x) + ebind f (BecomeWith g) = BecomeWith (f . g) scase = SDescriptive -- Abstractions @@ -76,6 +79,11 @@ data Spine | App Spine (El N) | Proj Spine Name +composeSpines :: Spine -> Spine -> Spine +composeSpines s Id = s +composeSpines s (App s' v) = App (composeSpines s s') v +composeSpines s (Proj s' x) = Proj (composeSpines s s') x + data Head = LocalVar FId | GlobalVar Name ~(El N) @@ -120,6 +128,7 @@ reflect head spine ~ty edesc = do case edesc of Just (Describe desc) -> k (Just desc) Just (Become v) -> v + Just (BecomeWith f) -> f (BareNeutral head spine) Nothing -> k Nothing local :: FId -> Ty N -> El N @@ -152,8 +161,18 @@ instance ToBare DecodedNeutral where -- Elements -------------------------------------------------------------------------------- +data InitNeutral = InitNeutral + { name :: BareNeutral + , initialOf :: Ty N + , spine :: Spine + } + +fullNeu :: InitNeutral -> BareNeutral +fullNeu n = BareNeutral n.name.head (composeSpines n.name.spine n.spine) + data El :: Case -> Type where Neu :: Neutral -> El N + InitNeu :: InitNeutral -> El N Code :: Ty c -> El c Lam :: ~(Ty N) -> Clo El c -> El c Cons :: Dict (Evaluation El c) -> El c @@ -190,6 +209,11 @@ data RecordType = RecordType , fieldTypes :: Dict (Locals -> Ty N) } +data InductiveType = InductiveType + { initialOf :: Ty N + , spine :: Spine + } + data EqualityType = EqualityType { at :: Ty N , lhs :: El N @@ -206,6 +230,7 @@ typeForProjection rt x fields = do data Ty :: Case -> Type where U :: Universe -> Ty N Decode :: DecodedNeutral -> Ty N + InitDecode :: InitNeutral -> Ty N Function :: FunctionType -> Ty N Record :: RecordType -> Ty D Eq :: EqualityType -> Ty N @@ -216,6 +241,7 @@ instance DebugVal (Ty c) where debugVal = \case U _ -> "U" Decode _ -> "Decode" + InitDecode _ -> "InitDecode" Function _ -> "Function" Record _ -> "Record" Eq _ -> "Eq" @@ -228,6 +254,7 @@ instance LevelOf (Ty c) where Decode n -> decodesInto n.universe Function ft -> levelOf ft.variant Record rt -> rt.level + InitDecode _ -> Level Set HSet Eq ety -> Level (levelOf ety.at).mlevel (equalityHLevelOf (levelOf ety.at).hlevel) BuiltinTy _ -> Level Set HSet -- Only Int/String so far EltOf _ _ -> Level Set HSet -- TODO @@ -236,8 +263,9 @@ behavior :: Ty c -> TypeBehavior behavior = \case U u -> LikeU u Decode n -> case n.description of - Just (Record rt) -> LikeRecord rt + Just t -> behavior t Nothing -> NoRules + InitDecode n -> LikeInductive n Function ft -> LikeFunction ft Record rt -> LikeRecord rt Eq _ -> NoRules @@ -254,7 +282,9 @@ decode (Neu n) = do case decode <$> n.description of Just (Describe desc) -> k (Just desc) Just (Become ty) -> ty + Just (BecomeWith f) -> f (BareNeutral n.head n.spine) Nothing -> k Nothing +decode (InitNeu n) = InitDecode n decode _ = panic "ill-typed decoding" -- Type behavior @@ -264,6 +294,7 @@ data TypeBehavior = LikeU Universe | LikeFunction FunctionType | LikeRecord RecordType + | LikeInductive InitNeutral | LikeBuiltinTy BuiltinTy | NoRules @@ -272,6 +303,7 @@ instance DebugVal TypeBehavior where LikeU _ -> "LikeU" LikeFunction _ -> "LikeFunction" LikeRecord _ -> "LikeRecord" + LikeInductive _ -> "LikeInductive" LikeBuiltinTy _ -> "LikeBuiltinTy" NoRules -> "NoRules" diff --git a/packages/coln-compiler/src/Coln/Elaborator/Coercion.hs b/packages/coln-compiler/src/Coln/Elaborator/Coercion.hs new file mode 100644 index 00000000..12a74a6b --- /dev/null +++ b/packages/coln-compiler/src/Coln/Elaborator/Coercion.hs @@ -0,0 +1,36 @@ +-- SPDX-FileCopyrightText: 2026 Coln contributors +-- +-- SPDX-License-Identifier: Apache-2.0 OR MIT + +module Coln.Elaborator.Coercion where + +import Coln.Common +import Coln.Core +import Coln.Core.Memoed qualified as M +import Coln.Core.Value qualified as V +import Coln.Elaborator.Judgment +import Coln.Elaborator.Rules.Polarity qualified as Polarity +import Coln.Elaborator.Rules.Universe qualified as Universe + +intoTyp :: Span -> Judgment N -> Typ N +intoTyp _ (FromTyp t) = t +intoTyp sp (FromSyn s) = Universe.elimSyn sp s +intoTyp _ (FromChk _ c) = Universe.elim TheoryU c + +intoSyn :: (V.HasEvaluation c) => DDoc -> Span -> Judgment c -> Syn c +intoSyn _ sp (FromTyp t) = Syn $ \e -> do + raw <- t.elab e + case universeFor (levelOf raw) of + Nothing -> do + let msg = "type" <+> prtIn e raw <+> "too large to fit in a universe" + failWith e.diagEnv sp TypeTooLarge msg + Just u -> pure (V.U u, M.code raw) +intoSyn _ _ (FromSyn s) = s +intoSyn use sp (FromChk nd _) = Syn $ \e -> do + let msg = "Type annotation required when using a" <+> nd <+> "as" <+> use + failWith e.diagEnv sp AnnotationRequired msg + +intoChk :: (V.HasEvaluation c) => Span -> Judgment c -> Chk c +intoChk sp (FromTyp t) = Universe.intro sp t +intoChk sp (FromSyn s) = Polarity.conv sp s +intoChk _ (FromChk _ c) = c diff --git a/packages/coln-compiler/src/Coln/Elaborator/Diagnostics.hs b/packages/coln-compiler/src/Coln/Elaborator/Diagnostics.hs index dc47885b..7bfe9ee8 100644 --- a/packages/coln-compiler/src/Coln/Elaborator/Diagnostics.hs +++ b/packages/coln-compiler/src/Coln/Elaborator/Diagnostics.hs @@ -29,6 +29,8 @@ data ElaboratorCode | MismatchedRecordField | VariableNotInScope | DebugMisc + | InductiveInConjunctive + | InitInConjunctive deriving (Eq, Ord) elaboratorCodeTable :: Map ElaboratorCode CodeMeta @@ -50,4 +52,6 @@ elaboratorCodeTable = , (MismatchedRecordField, CodeMeta 13 SError Nothing) , (VariableNotInScope, CodeMeta 14 SError Nothing) , (DebugMisc, CodeMeta 15 SDebug Nothing) + , (InductiveInConjunctive, CodeMeta 16 SError Nothing) + , (InitInConjunctive, CodeMeta 17 SError Nothing) ] diff --git a/packages/coln-compiler/src/Coln/Elaborator/Environment.hs b/packages/coln-compiler/src/Coln/Elaborator/Environment.hs index 2f5508ce..5f94e5a8 100644 --- a/packages/coln-compiler/src/Coln/Elaborator/Environment.hs +++ b/packages/coln-compiler/src/Coln/Elaborator/Environment.hs @@ -5,7 +5,7 @@ module Coln.Elaborator.Environment where import Coln.Common -import Coln.Core +import Coln.Core hiding (GlobalEntry (..)) import Coln.Core.Value qualified as BN (BareNeutral (..)) import Coln.Core.Value qualified as V import Coln.Elaborator.Diagnostics @@ -17,48 +17,57 @@ data Scope = Scope { len :: Int , names :: Bwd Name , locals :: V.Locals - , ctx :: Bwd (V.Ty N) + , ctx :: Bwd (V.Ty N, Mode) + , mode :: Mode } -emptyScope :: Scope +lock :: Scope -> Scope +lock sc = sc{mode = Conjunctive, ctx = fmap (\(a, _) -> (a, Inductive)) sc.ctx} + +unlock :: Scope -> Scope +unlock sc = sc{mode = Inductive} + +emptyScope :: Mode -> Scope emptyScope = Scope 0 BwdNil V.LNil BwdNil instance HasShape Scope where shape :: Scope -> CtxShape shape c = CtxShape c.len c.names -bind :: Name -> V.Ty N -> Scope -> Scope -bind x a c = do +bind :: Name -> V.Ty N -> Mode -> Scope -> Scope +bind x a m c = do let v = V.local (FId c.len) a - let_ x v a c + let_ x v a m c -let_ :: Name -> V.El N -> V.Ty N -> Scope -> Scope -let_ x v a c = +let_ :: Name -> V.El N -> V.Ty N -> Mode -> Scope -> Scope +let_ x v a m c = Scope (c.len + 1) (c.names :> x) (V.LSnoc c.locals v) - (c.ctx :> a) + (c.ctx :> (a, m)) + c.mode -withBound :: Name -> V.Ty N -> Scope -> (V.El N -> Scope -> a) -> a -withBound x a c body = do +withBound :: Name -> V.Ty N -> Mode -> Scope -> (V.El N -> Scope -> a) -> a +withBound x a m c body = do let v = V.local (FId c.len) a - let c' = let_ x v a c + let c' = let_ x v a m c body v c' -instance Lookup Scope Name (BId, V.El N, V.Ty N) where +instance Lookup Scope Name (BId, V.El N, V.Ty N, Mode) where lookup sc x = go sc.len sc.len sc.names sc.locals sc.ctx 0 where + go :: Int -> Int -> Bwd Name -> V.Locals -> Bwd (V.Ty N, Mode) -> Int -> Maybe (BId, V.El N, V.Ty N, Mode) go 0 0 BwdNil V.LNil BwdNil _ = Nothing go 0 0 BwdNil (V.LSnocChunk vs chunk) BwdNil i | Vector.length chunk == 0 = go 0 0 BwdNil vs BwdNil i - go n _ (xs :> x') (V.LSnoc vs v) (ts :> t) i - | x' == x = Just (BId i, v, t) + go n _ (xs :> x') (V.LSnoc vs v) (ts :> (t, m)) i + | x' == x = Just (BId i, v, t, m) | otherwise = go (n - 1) (n - 1) xs vs ts (i + 1) - go n m xs@(xs' :> x') vs@(V.LSnocChunk vs' chunk) ts@(ts' :> t) i - | m - n == Vector.length chunk = go n n xs vs' ts i - | x' == x = Just (BId i, chunk Vector.! (Vector.length chunk + n - m - 1), t) - | otherwise = go n m xs' vs ts' (i + 1) + go n n' xs@(xs' :> x') vs@(V.LSnocChunk vs' chunk) ts@(ts' :> (t, m)) i + | n' - n == Vector.length chunk = go n n xs vs' ts i + | x' == x = Just (BId i, chunk Vector.! (Vector.length chunk + n - n' - 1), t, m) + | otherwise = go n n' xs' vs ts' (i + 1) go _ _ _ _ _ _ = panic "misaligned local variable details" -- * Target @@ -91,21 +100,21 @@ data ElabEnv c = ElabEnv instance HasShape (ElabEnv c) where shape e = shape e.scope -emptyElabEnvFor :: DiagnosticEnv ElaboratorCode -> Globals -> Name -> V.Ty N -> ElabEnv D -emptyElabEnvFor diagEnv globals x ty = do +emptyElabEnvFor :: DiagnosticEnv ElaboratorCode -> Globals -> Mode -> Name -> V.Ty N -> ElabEnv D +emptyElabEnvFor diagEnv globals m x ty = do let v = V.reflect (V.GlobalVar x v) V.Id ty Nothing ElabEnv { target = (TargetNamed (V.BareNeutral (V.GlobalVar x v) V.Id)) - , scope = emptyScope + , scope = emptyScope m , globals = globals , diagEnv = diagEnv } -emptyElabEnv :: DiagnosticEnv ElaboratorCode -> Globals -> ElabEnv N -emptyElabEnv diagEnv globals = +emptyElabEnv :: DiagnosticEnv ElaboratorCode -> Globals -> Mode -> ElabEnv N +emptyElabEnv diagEnv globals m = ElabEnv { target = TargetAnonymous - , scope = emptyScope + , scope = emptyScope m , globals = globals , diagEnv = diagEnv } diff --git a/packages/coln-compiler/src/Coln/Elaborator/Judgment.hs b/packages/coln-compiler/src/Coln/Elaborator/Judgment.hs index d6473c5d..ceb58a42 100644 --- a/packages/coln-compiler/src/Coln/Elaborator/Judgment.hs +++ b/packages/coln-compiler/src/Coln/Elaborator/Judgment.hs @@ -11,10 +11,6 @@ module Coln.Elaborator.Judgment ( Chk (..), Judgment (..), useIs, - intoTyp, - intoSyn, - intoChk, - annotate, ) where @@ -43,55 +39,6 @@ useIs @c f e = fmap change $ f e{target = TargetAnonymous} SNominative -> id SDescriptive -> M.is -intoTyp :: Span -> Judgment N -> Typ N -intoTyp _ (FromTyp t) = t -intoTyp sp (FromSyn s) = Typ $ \e -> do - (ty, el) <- s.elab e - case V.behavior ty of - V.LikeU _ -> pure $ M.decode el - _ -> do - let msg = "tried to use a value of type" <+> prtIn e ty <+> "as a type" - failWith e.diagEnv sp TypeMismatch msg -intoTyp _ (FromChk _ c) = Typ $ \e -> do - el <- c.elab e $ V.U TheoryU - pure $ M.decode el - -intoSyn :: (V.HasEvaluation c) => DDoc -> Span -> Judgment c -> Syn c -intoSyn _ sp (FromTyp t) = Syn $ \e -> do - raw <- t.elab e - case universeFor (levelOf raw) of - Nothing -> do - let msg = "type" <+> prtIn e raw <+> "too large to fit in a universe" - failWith e.diagEnv sp TypeTooLarge msg - Just u -> pure (V.U u, M.code raw) -intoSyn _ _ (FromSyn s) = s -intoSyn use sp (FromChk nd _) = Syn $ \e -> do - let msg = "Type annotation required when using a" <+> nd <+> "as" <+> use - failWith e.diagEnv sp AnnotationRequired msg - -intoChk :: (V.HasEvaluation c) => Span -> Judgment c -> Chk c -intoChk sp (FromTyp t) = Chk $ \e ty -> do - raw <- t.elab e - case V.behavior ty of - V.LikeU u -> do - case leq (levelOf raw) (decodesInto u) of - True -> pure $ M.code raw - False -> do - let msg = "type" <+> prtIn e raw <+> "too large for universe" <+> pretty u - failWith e.diagEnv sp TypeTooLarge msg - _ -> do - let msg = "cannot check type" <+> prtIn e raw <+> "at non-universe type" <+> prtIn e.scope ty - failWith e.diagEnv sp TypeAtNonUniverse msg -intoChk sp (FromSyn s) = Chk $ \e ty -> do - (ty', el) <- s.elab e - case defEq (shape e) ty ty' of - Right _ -> pure el - Left err -> do - let msg = "expected type" <+> prtIn e.scope ty <> ", but got type" <+> prtIn e.scope ty' - let note = Just $ dpretty err - failWithNote e.diagEnv sp TypeMismatch msg note -intoChk _ (FromChk _ c) = c - annotate :: Typ N -> Chk c -> Syn c annotate t c = Syn \e -> do a <- t.elab (e{target = TargetAnonymous}) diff --git a/packages/coln-compiler/src/Coln/Elaborator/Rules/Function.hs b/packages/coln-compiler/src/Coln/Elaborator/Rules/Function.hs index 16945f76..ca3ed349 100644 --- a/packages/coln-compiler/src/Coln/Elaborator/Rules/Function.hs +++ b/packages/coln-compiler/src/Coln/Elaborator/Rules/Function.hs @@ -10,33 +10,37 @@ import Coln.Core.Syntax qualified as S import Coln.Core.Value qualified as V import Coln.Elaborator.Judgment -variantFor :: Ty N -> Ty N -> Span -> ElabEnv c -> IO FunctionVariant -variantFor dom cod sp e = +variantFor :: Mode -> Ty N -> Ty N -> Span -> ElabEnv c -> IO FunctionVariant +variantFor m dom cod sp e = case functionMLevelFor (levelOf dom).mlevel (levelOf cod).mlevel of - Just l -> pure (FunctionVariant l (levelOf cod).hlevel) + Just l -> pure (FunctionVariant l (levelOf cod).hlevel m) Nothing -> do let msg = "higher-order theories are not supported" failWith e.diagEnv sp FunctionDomainTooLarge msg -data Binder = Anonymous (Typ N) | Named Name (Typ N) +data Binder = Anonymous Mode (Typ N) | Named Mode Name (Typ N) + +shiftToMode :: Mode -> Scope -> Scope +shiftToMode Conjunctive sc = sc +shiftToMode Inductive sc = unlock sc formation :: Span -> Binder -> Typ N -> Typ N -formation sp (Anonymous dom) cod = Typ \e -> do - edom <- dom.elab e +formation sp (Anonymous m dom) cod = Typ \e -> do + edom <- dom.elab (e{scope = shiftToMode m e.scope}) ecod <- cod.elab e - v <- variantFor edom ecod sp e + v <- variantFor m edom ecod sp e pure $ function e.scope.locals v edom (S.AbsConst ecod) -formation sp (Named x dom) cod = Typ \e -> do - edom <- dom.elab e - ecod <- cod.elab $ e{scope = bind x edom.val e.scope} - v <- variantFor edom ecod sp e +formation sp (Named m x dom) cod = Typ \e -> do + edom <- dom.elab (e{scope = shiftToMode m e.scope}) + ecod <- cod.elab $ e{scope = bind x edom.val m e.scope} + v <- variantFor m edom ecod sp e pure $ function e.scope.locals v edom (S.Abs x ecod) intro :: (V.HasEvaluation c) => Span -> Name -> Chk c -> Chk c intro sp x body = Chk \e a -> case V.behavior a of V.LikeFunction ft -> do - ebody <- withBound x ft.dom e.scope $ \v scope' -> + ebody <- withBound x ft.dom ft.variant.domainMode e.scope $ \v scope' -> body.elab (e{scope = scope', target = appTarget e.target v}) (V.appClo ft.cod v) @@ -50,7 +54,7 @@ elim sp callee arg = Syn $ \e -> do (ty, ecallee) <- callee.elab e case V.behavior ty of V.LikeFunction ft -> do - earg <- arg.elab e ft.dom + earg <- arg.elab (e{scope = shiftToMode ft.variant.domainMode e.scope}) ft.dom pure (V.appClo ft.cod earg.val, app ecallee earg) _ -> do let msg = "tried to apply a value that was not of a function type" diff --git a/packages/coln-compiler/src/Coln/Elaborator/Rules/Initial.hs b/packages/coln-compiler/src/Coln/Elaborator/Rules/Initial.hs new file mode 100644 index 00000000..b2fc2919 --- /dev/null +++ b/packages/coln-compiler/src/Coln/Elaborator/Rules/Initial.hs @@ -0,0 +1,22 @@ +-- SPDX-FileCopyrightText: 2026 Coln contributors +-- +-- SPDX-License-Identifier: Apache-2.0 OR MIT + +module Coln.Elaborator.Rules.Initial where + +import Prelude hiding (init) + +import Coln.Common +import Coln.Core +import Coln.Elaborator.Environment +import Coln.Elaborator.Judgment + +create :: Span -> Typ N -> Syn D +create sp t = Syn \e -> do + case e.scope.mode of + Inductive -> pure () + Conjunctive -> do + let msg = "cannot create initial model in conjunctive mode" + failWith e.diagEnv sp InitInConjunctive msg + a <- t.elab (e{scope = lock e.scope, target = TargetAnonymous}) + pure (a.val, init a) diff --git a/packages/coln-compiler/src/Coln/Elaborator/Rules/Polarity.hs b/packages/coln-compiler/src/Coln/Elaborator/Rules/Polarity.hs new file mode 100644 index 00000000..8ee54055 --- /dev/null +++ b/packages/coln-compiler/src/Coln/Elaborator/Rules/Polarity.hs @@ -0,0 +1,26 @@ +-- SPDX-FileCopyrightText: 2026 Coln contributors +-- +-- SPDX-License-Identifier: Apache-2.0 OR MIT + +module Coln.Elaborator.Rules.Polarity where + +import Coln.Common +import Coln.Core +import Coln.Core.Value qualified as V +import Coln.Elaborator.Judgment + +conv :: (V.HasEvaluation c) => Span -> Syn c -> Chk c +conv sp s = Chk \e a -> do + (a', m) <- s.elab e + case defEq (shape e) a a' of + Right _ -> pure m + Left err -> do + let msg = "expected type" <+> prtIn e.scope a <> ", but got type" <+> prtIn e.scope a' + let note = Just $ dpretty err + failWithNote e.diagEnv sp TypeMismatch msg note + +annot :: (V.HasEvaluation c) => Chk c -> Typ N -> Syn c +annot c t = Syn \e -> do + a <- t.elab (e{target = TargetAnonymous}) + m <- c.elab e a.val + pure (a.val, m) diff --git a/packages/coln-compiler/src/Coln/Elaborator/Rules/Record.hs b/packages/coln-compiler/src/Coln/Elaborator/Rules/Record.hs index c0af41ba..b51501b8 100644 --- a/packages/coln-compiler/src/Coln/Elaborator/Rules/Record.hs +++ b/packages/coln-compiler/src/Coln/Elaborator/Rules/Record.hs @@ -22,7 +22,7 @@ formation fieldTyps = Typ $ \e -> do let go _ [] = pure (Level Set HUnit, []) go e' ((FieldDeclaration x typ) : rest) = do ty <- typ.elab e' - (l, fieldTys) <- go (e'{scope = bind x ty.val e'.scope}) rest + (l, fieldTys) <- go (e'{scope = bind x ty.val Conjunctive e'.scope}) rest pure (maxLevel l (levelOf ty), (x, ty) : fieldTys) go e' ((FieldDeclarationDebug ds) : rest) = do runDebug e' ds diff --git a/packages/coln-compiler/src/Coln/Elaborator/Rules/Universe.hs b/packages/coln-compiler/src/Coln/Elaborator/Rules/Universe.hs index 2c3ecc46..37d02cf9 100644 --- a/packages/coln-compiler/src/Coln/Elaborator/Rules/Universe.hs +++ b/packages/coln-compiler/src/Coln/Elaborator/Rules/Universe.hs @@ -4,8 +4,38 @@ module Coln.Elaborator.Rules.Universe where +import Coln.Common import Coln.Core +import Coln.Core.Value qualified as V import Coln.Elaborator.Judgment formation :: Universe -> Typ N formation u = Typ \_ -> pure $ univ u + +intro :: (V.HasEvaluation c) => Span -> Typ c -> Chk c +intro sp t = Chk $ \e ty -> do + raw <- t.elab e + case V.behavior ty of + V.LikeU u -> do + case leq (levelOf raw) (decodesInto u) of + True -> pure $ code raw + False -> do + let msg = "type" <+> prtIn e raw <+> "too large for universe" <+> pretty u + failWith e.diagEnv sp TypeTooLarge msg + _ -> do + let msg = "cannot check type" <+> prtIn e raw <+> "at non-universe type" <+> prtIn e.scope ty + failWith e.diagEnv sp TypeAtNonUniverse msg + +elim :: Universe -> Chk N -> Typ N +elim u c = Typ \e -> do + el <- c.elab e $ V.U u + pure $ decode el + +elimSyn :: Span -> Syn N -> Typ N +elimSyn sp s = Typ \e -> do + (a, el) <- s.elab e + case V.behavior a of + V.LikeU _ -> pure $ decode el + _ -> do + let msg = "expected element of universe type" + failWith e.diagEnv sp TypeAtNonUniverse msg diff --git a/packages/coln-compiler/src/Coln/Elaborator/Rules/Variable.hs b/packages/coln-compiler/src/Coln/Elaborator/Rules/Variable.hs index 300e1fd5..c287beab 100644 --- a/packages/coln-compiler/src/Coln/Elaborator/Rules/Variable.hs +++ b/packages/coln-compiler/src/Coln/Elaborator/Rules/Variable.hs @@ -14,11 +14,16 @@ import Coln.Elaborator.Environment import Coln.Elaborator.Judgment find :: Span -> Name -> Syn N -find sp x = Syn \e -> - case lookup e.scope x of - Just (i, v, ty) -> pure (ty, localVar i v) +find sp x = Syn \e -> do + (ty, tm, m) <- case lookup e.scope x of + Just (i, v, ty, m) -> pure (ty, localVar i v, m) Nothing -> case lookup e.globals x of - Just ge -> pure (ge.ty, globalVar x ge.val) + Just ge -> pure (ge.ty, globalVar x ge.val, ge.mode) Nothing -> do let msg = "no such variable" <+> dpretty x <+> "in scope" failWith e.diagEnv sp VariableNotInScope msg + case (m, e.scope.mode) of + (Inductive, Conjunctive) -> do + let msg = "cannot use inductively bound variable in a conjunctive context" + failWith e.diagEnv sp InductiveInConjunctive msg + _ -> pure (ty, tm) diff --git a/packages/coln-compiler/src/Coln/Frontend/Diagnostics.hs b/packages/coln-compiler/src/Coln/Frontend/Diagnostics.hs index 095e484b..7f37db5f 100644 --- a/packages/coln-compiler/src/Coln/Frontend/Diagnostics.hs +++ b/packages/coln-compiler/src/Coln/Frontend/Diagnostics.hs @@ -14,6 +14,8 @@ data ParserCode | UnexpectedField | UnexpectedDescriptive | UnknownCommand + | UnknownModifiers + | UnknownMode deriving (Eq, Ord) parserCodeTable :: Map ParserCode CodeMeta @@ -25,4 +27,6 @@ parserCodeTable = , (UnexpectedField, CodeMeta 3 SError Nothing) , (UnexpectedDescriptive, CodeMeta 4 SError Nothing) , (UnknownCommand, CodeMeta 5 SError Nothing) + , (UnknownModifiers, CodeMeta 6 SError Nothing) + , (UnknownMode, CodeMeta 7 SError Nothing) ] diff --git a/packages/coln-compiler/src/Coln/Frontend/Notation.hs b/packages/coln-compiler/src/Coln/Frontend/Notation.hs index 86a9b646..41d9d6d8 100644 --- a/packages/coln-compiler/src/Coln/Frontend/Notation.hs +++ b/packages/coln-compiler/src/Coln/Frontend/Notation.hs @@ -22,6 +22,7 @@ lexConfig = , ("showtype", K.Decl) , ("showlevel", K.Decl) , ("expand", K.Decl) + , ("ind", K.Modifier) , ("end", K.End) , ("Set", K.AKeyword) , ("Prop", K.AKeyword) diff --git a/packages/coln-compiler/src/Coln/Frontend/Parser.hs b/packages/coln-compiler/src/Coln/Frontend/Parser.hs index 7fe780c5..21ef6a68 100644 --- a/packages/coln-compiler/src/Coln/Frontend/Parser.hs +++ b/packages/coln-compiler/src/Coln/Frontend/Parser.hs @@ -1,243 +1,11 @@ -- SPDX-FileCopyrightText: 2026 Coln contributors -- -- SPDX-License-Identifier: Apache-2.0 OR MIT -{-# LANGUAGE TypeAbstractions #-} -module Coln.Frontend.Parser where +module Coln.Frontend.Parser ( + module Coln.Frontend.Parser.Expr, + module Coln.Frontend.Parser.Top, +) where -import Control.Exception (try) -import Data.Foldable -import Data.Functor.Contravariant (contramap) -import Data.List.NonEmpty (NonEmpty (..)) -import FNotation (Ntn) -import FNotation qualified as N - -import Coln.Common -import Coln.Core -import Coln.Core.Layout -import Coln.Core.Memoed qualified as M -import Coln.Core.Value qualified as V -import Coln.Diagnostics -import Coln.Elaborator.Debug -import Coln.Elaborator.Environment -import Coln.Elaborator.Judgment -import Coln.Elaborator.Rules.Builtin qualified as Builtin -import Coln.Elaborator.Rules.Equality qualified as Equality -import Coln.Elaborator.Rules.Function qualified as Function -import Coln.Elaborator.Rules.Record qualified as Record -import Coln.Elaborator.Rules.Universe qualified as Universe -import Coln.Elaborator.Rules.Variable qualified as Variable -import Coln.Frontend.Diagnostics -import Coln.Frontend.Notation - -type ParseEnv = DiagnosticEnv ColnCode - -top :: ParseEnv -> [Ntn] -> IO Globals -top e = foldlM (decl' e) emptyGlobals - -topFromText :: Reporter ColnCode -> File -> IO Globals -topFromText r f = do - ts <- N.lex lexConfig (contramap LexerCode r) f - ns <- N.read readConfig (contramap ReaderCode r) f ts - top (DiagnosticEnv r f) ns - -decl' :: ParseEnv -> Globals -> Ntn -> IO Globals -decl' e g n = do - try (decl e g n) >>= \case - Right g' -> pure g' - Left (_ :: FailException) -> pure g - -decl :: ParseEnv -> Globals -> Ntn -> IO Globals -decl e g (N.Decl "theory" n _) = do - (x, ge) <- idef e g (M.univ TheoryU) n - pure $ addGlobalEntry x ge g -decl e g (N.Decl "def" n _) = do - (x, ge) <- def e g n - pure $ addGlobalEntry x ge g -decl e g (N.Block "realm" (Just head) body _) = do - (x, r) <- realm e g head body - pure $ addRealm x r g -decl e _ n = unexpectedNotation e n "top-level declaration" - -definition :: ParseEnv -> Ntn -> IO (Ntn, Ntn) -definition _ (N.Infix n0 (N.Keyword ":=" _) n1) = pure (n0, n1) -definition e n = unexpectedNotation e n "notation of the form ` := `" - -annot :: ParseEnv -> Ntn -> IO (Ntn, Ntn) -annot _ (N.Infix n0 (N.Keyword ":" _) n1) = pure (n0, n1) -annot e n = unexpectedNotation e n "type-annotated expression, e.g. ` : `" - -debugCommand :: ParseEnv -> Span -> Name -> Ntn -> IO DebugCommand -debugCommand e _ "showtype" n = do - s <- syn e "argument to showtype" n - pure $ ShowType (N.span n) s -debugCommand e _ "showtypeb" n = do - s <- syn e "argument to showtypeb" n - pure $ ShowTypeBehavior (N.span n) s -debugCommand e _ "showlevel" n = do - ty <- typ e n - pure $ ShowLevel (N.span n) ty -debugCommand e _ "expand" n = do - s <- syn e "argument to expand" n - pure $ Expand (N.span n) s -debugCommand e sp x _ = unknownCommand e sp x - -fieldDecl :: ParseEnv -> Ntn -> IO Record.FieldDeclaration -fieldDecl e (N.Infix (N.Ident x _) (N.Keyword ":" _) n) = - Record.FieldDeclaration x <$> typ e n -fieldDecl e (N.Decl c n sp) = - Record.FieldDeclarationDebug <$> debugCommand e sp c n -fieldDecl e n = unexpectedNotation e n "field declaration of the form ` : `" - -fieldSetting :: (V.HasEvaluation c) => ParseEnv -> Ntn -> IO (Record.FieldSetting c) -fieldSetting e (N.Infix (N.Ident x sp) (N.Keyword ":=" _) body) = - Record.FieldSetting x <$> chk e body <*> pure sp -fieldSetting e n = unexpectedNotation e n "field setting of the form ` := `" - -ident :: ParseEnv -> Ntn -> IO Name -ident _ (N.Ident x _) = pure x -ident e n = unexpectedNotation e n "identifier" - -argBinding :: ParseEnv -> Ntn -> IO (Span, Name, Ntn) -argBinding e n@(N.Infix n0 (N.Keyword ":" _) n1) = do - x <- ident e n0 - pure (N.span n, x, n1) -argBinding e n = unexpectedNotation e n "argument binding of the form ` : `" - -unpackArgs :: ParseEnv -> Ntn -> IO (Name, [(Span, Name, Ntn)]) -unpackArgs e (N.Group (xN :| argsN)) = do - x <- ident e xN - args <- mapM (argBinding e) argsN - pure (x, args) - -def :: ParseEnv -> Globals -> Ntn -> IO (Name, GlobalEntry) -def e g n = do - (head_n, body_n) <- definition e n - (pat_n, ty_n) <- annot e head_n - (name, args) <- unpackArgs e pat_n - ret_typ <- typ e ty_n - body_chk <- chk e body_n - (ty_j, term_j) <- withArgs e args (ret_typ, body_chk) - let tyElabE = emptyElabEnv (contramap ElaboratorCode e) g - ty <- ty_j.elab tyElabE - let elabE = emptyElabEnvFor (contramap ElaboratorCode e) g name ty.val - term <- term_j.elab elabE ty.val - let entry = M.mkGlobal name ty.val term - pure (name, entry) - -idef :: ParseEnv -> Globals -> M.Ty N -> Ntn -> IO (Name, GlobalEntry) -idef e g ret_ty n = do - (pat_n, body_n) <- definition e n - (name, args) <- unpackArgs e pat_n - body_chk <- chk e body_n - (ty_j, term_j) <- withArgs e args $ (Typ \_ -> pure ret_ty, body_chk) - let tyElabE = emptyElabEnv (contramap ElaboratorCode e) g - ty <- ty_j.elab tyElabE - let elabE = emptyElabEnvFor (contramap ElaboratorCode e) g name ty.val - term <- term_j.elab elabE ty.val - let entry = M.mkGlobal name ty.val term - pure (name, entry) - -realmHead :: ParseEnv -> Ntn -> IO (Name, Ntn) -realmHead _ (N.Infix (N.Ident x _) (N.Keyword "@" _) n) = pure (x, n) -realmHead e n = unexpectedNotation e n "realm head" - -realm :: ParseEnv -> Globals -> Ntn -> [Ntn] -> IO (Name, Realm) -realm e g head _defs = do - (x, theory_n) <- realmHead e head - theory_typ <- typ e theory_n - theory <- theory_typ.elab (emptyElabEnv (contramap ElaboratorCode e) g) - let (gt, root) = layoutTop x theory.val - pure (x, Realm gt root.val theory.val) - -withArgs :: (V.HasEvaluation c) => ParseEnv -> [(Span, Name, Ntn)] -> (Typ N, Chk c) -> IO (Typ N, Chk c) -withArgs e args base = foldrM go base args - where - go :: (V.HasEvaluation c) => (Span, Name, Ntn) -> (Typ N, Chk c) -> IO (Typ N, Chk c) - go (sp, name, n) (t, c) = do - argtyp <- typ e n - pure $ - ( Function.formation sp (Function.Named name argtyp) t - , Function.intro sp name c - ) - -fromSynN :: (V.HasEvaluation c) => Syn N -> Judgment c -fromSynN @c s = case V.scase @c of - SNominative -> FromSyn s - SDescriptive -> FromSyn $ Syn \e -> do - (a, m) <- s.elab (e{target = TargetAnonymous}) - pure (a, M.is m) - -fromTypN :: (V.HasEvaluation c) => Typ N -> Judgment c -fromTypN @c t = case V.scase @c of - SNominative -> FromTyp t - SDescriptive -> FromTyp $ Typ \e -> do - m <- t.elab (e{target = TargetAnonymous}) - pure $ M.isTy m - -fromTypD :: (V.HasEvaluation c) => ParseEnv -> Span -> Typ D -> IO (Judgment c) -fromTypD @c e sp t = case V.scase @c of - SNominative -> do - let msg = "expected nominative type, got descriptive type" - failWith e sp (ParserCode UnexpectedDescriptive) msg - SDescriptive -> pure $ FromTyp t - -expr :: (V.HasEvaluation c) => ParseEnv -> Ntn -> IO (Judgment c) -expr e n = case n of - N.Ident name s -> pure $ fromSynN $ Variable.find s name - N.Juxt n0 n1 -> do - s <- syn e "target of elimination" n0 - fromSynN <$> elim e s n1 - N.Keyword "Set" _ -> pure $ fromTypN $ Universe.formation SetU - N.Keyword "Prop" _ -> pure $ fromTypN $ Universe.formation PropU - N.Keyword "Int" _ -> pure $ fromTypN $ Builtin.formation BuiltinInt - N.Keyword "String" _ -> pure $ fromTypN $ Builtin.formation BuiltinString - N.Infix arg n@(N.Keyword "->" _) body -> - fromTypN <$> (Function.formation (N.span n) <$> binder e arg <*> typ e body) - N.Infix arg n@(N.Keyword "=>" _) body -> - FromChk "lambda expression" - <$> (Function.intro (N.span n) <$> ident e arg <*> chk e body) - n@(N.Infix lhs (N.Keyword "=" _) rhs) -> - fromTypN - <$> ( Equality.formation (N.span n) - <$> syn e "term in equality" lhs - <*> syn e "term in equality" rhs - ) - N.Block "sig" Nothing ns _ -> do - t <- Record.formation <$> traverse (fieldDecl e) ns - fromTypD e (N.span n) t - N.Block "struct" Nothing ns s -> - FromChk "struct expression" <$> (Record.intro s <$> traverse (fieldSetting e) ns) - N.Int i _ -> pure $ fromSynN $ Builtin.intro $ LitInt i - N.String s _ -> pure $ fromSynN $ Builtin.intro $ LitString s - n -> unexpectedNotation e n "expression" - -syn :: (V.HasEvaluation c) => ParseEnv -> DDoc -> Ntn -> IO (Syn c) -syn e use n = intoSyn use (N.span n) <$> expr e n - -chk :: (V.HasEvaluation c) => ParseEnv -> Ntn -> IO (Chk c) -chk e n = intoChk (N.span n) <$> expr e n - -typ :: ParseEnv -> Ntn -> IO (Typ N) -typ e n = intoTyp (N.span n) <$> expr e n - -elim :: ParseEnv -> Syn N -> Ntn -> IO (Syn N) -elim e j = \case - N.Field x s -> pure $ Record.elim s j x - arg -> Function.elim (N.span arg) j <$> chk e arg - -binder :: ParseEnv -> Ntn -> IO Function.Binder -binder e = \case - N.Infix name (N.Keyword ":" _) arg -> - Function.Named <$> ident e name <*> typ e arg - n -> Function.Anonymous <$> typ e n - -unexpectedNotation :: ParseEnv -> Ntn -> DDoc -> IO a -unexpectedNotation e n c = do - let msg = "unexpected notation for" <+> c <> ":" <+> N.head n - failWith e (N.span n) (ParserCode UnexpectedNotation) msg - -unknownCommand :: ParseEnv -> Span -> Name -> IO a -unknownCommand e sp x = do - let msg = "unknown command:" <+> dpretty x - failWith e sp (ParserCode UnknownCommand) msg +import Coln.Frontend.Parser.Expr +import Coln.Frontend.Parser.Top diff --git a/packages/coln-compiler/src/Coln/Frontend/Parser/Expr.hs b/packages/coln-compiler/src/Coln/Frontend/Parser/Expr.hs new file mode 100644 index 00000000..2b094e40 --- /dev/null +++ b/packages/coln-compiler/src/Coln/Frontend/Parser/Expr.hs @@ -0,0 +1,160 @@ +-- SPDX-FileCopyrightText: 2026 Coln contributors +-- +-- SPDX-License-Identifier: Apache-2.0 OR MIT +{-# LANGUAGE TypeAbstractions #-} + +module Coln.Frontend.Parser.Expr where + +import FNotation (Ntn) +import FNotation qualified as N + +import Coln.Common +import Coln.Core +import Coln.Core.Memoed qualified as M +import Coln.Core.Value qualified as V +import Coln.Elaborator.Coercion +import Coln.Elaborator.Debug +import Coln.Elaborator.Environment +import Coln.Elaborator.Judgment +import Coln.Elaborator.Rules.Builtin qualified as Builtin +import Coln.Elaborator.Rules.Equality qualified as Equality +import Coln.Elaborator.Rules.Function qualified as Function +import Coln.Elaborator.Rules.Initial qualified as Initial +import Coln.Elaborator.Rules.Record qualified as Record +import Coln.Elaborator.Rules.Universe qualified as Universe +import Coln.Elaborator.Rules.Variable qualified as Variable + +import Coln.Frontend.Diagnostics + +type ParserEnv = DiagnosticEnv ParserCode + +debugCommand :: ParserEnv -> Span -> Name -> Ntn -> IO DebugCommand +debugCommand e _ "showtype" n = do + s <- syn e "argument to showtype" n + pure $ ShowType (N.span n) s +debugCommand e _ "showtypeb" n = do + s <- syn e "argument to showtypeb" n + pure $ ShowTypeBehavior (N.span n) s +debugCommand e _ "showlevel" n = do + ty <- typ e n + pure $ ShowLevel (N.span n) ty +debugCommand e _ "expand" n = do + s <- syn e "argument to expand" n + pure $ Expand (N.span n) s +debugCommand e sp x _ = unknownCommand e sp x + +binder :: ParserEnv -> Ntn -> IO Function.Binder +binder e = \case + N.Infix name (N.Keyword ":" _) arg -> do + (mode, x) <- modalIdent e Inductive name + Function.Named mode x <$> typ e arg + n -> Function.Anonymous Inductive <$> typ e n + +fieldDecl :: ParserEnv -> Ntn -> IO Record.FieldDeclaration +fieldDecl e (N.Infix (N.Ident x _) (N.Keyword ":" _) n) = + Record.FieldDeclaration x <$> typ e n +fieldDecl e (N.Decl c n sp) = + Record.FieldDeclarationDebug <$> debugCommand e sp c n +fieldDecl e n = unexpectedNotation e n "field declaration of the form ` : `" + +fieldSetting :: (V.HasEvaluation c) => ParserEnv -> Ntn -> IO (Record.FieldSetting c) +fieldSetting e (N.Infix (N.Ident x sp) (N.Keyword ":=" _) body) = + Record.FieldSetting x <$> chk e body <*> pure sp +fieldSetting e n = unexpectedNotation e n "field setting of the form ` := `" + +ident :: ParserEnv -> Ntn -> IO Name +ident _ (N.Ident x _) = pure x +ident e n = unexpectedNotation e n "identifier" + +modalIdent :: ParserEnv -> Mode -> Ntn -> IO (Mode, Name) +modalIdent _ def (N.Ident x _) = pure (def, x) +modalIdent _ _ (N.Juxt (N.Mode "i" _) (N.Ident x _)) = pure (Inductive, x) +modalIdent _ _ (N.Juxt (N.Mode "c" _) (N.Ident x _)) = pure (Conjunctive, x) +modalIdent e _ (N.Juxt (N.Mode _ sp) (N.Ident _ _)) = + failWith e sp UnknownMode "unknown mode" +modalIdent e _ n = unexpectedNotation e n "identifier, possibly with mode annotation" + +unexpectedNotation :: ParserEnv -> Ntn -> DDoc -> IO a +unexpectedNotation e n c = do + let msg = "unexpected notation for" <+> c <> ":" <+> N.head n + failWith e (N.span n) UnexpectedNotation msg + +unknownCommand :: ParserEnv -> Span -> Name -> IO a +unknownCommand e sp x = do + let msg = "unknown command:" <+> dpretty x + failWith e sp UnknownCommand msg + +fromSynN :: (V.HasEvaluation c) => Syn N -> Judgment c +fromSynN @c s = case V.scase @c of + SNominative -> FromSyn s + SDescriptive -> FromSyn $ Syn \e -> do + (a, m) <- s.elab (e{target = TargetAnonymous}) + pure (a, M.is m) + +fromSynD :: (V.HasEvaluation c) => ParserEnv -> Span -> Syn D -> IO (Judgment c) +fromSynD @c e sp s = case V.scase @c of + SNominative -> do + let msg = "expected nominative expression, got descriptive expression" + failWith e sp UnexpectedDescriptive msg + SDescriptive -> pure $ FromSyn s + +fromTypN :: (V.HasEvaluation c) => Typ N -> Judgment c +fromTypN @c t = case V.scase @c of + SNominative -> FromTyp t + SDescriptive -> FromTyp $ Typ \e -> do + m <- t.elab (e{target = TargetAnonymous}) + pure $ M.isTy m + +fromTypD :: (V.HasEvaluation c) => ParserEnv -> Span -> Typ D -> IO (Judgment c) +fromTypD @c e sp t = case V.scase @c of + SNominative -> do + let msg = "expected nominative type, got descriptive type" + failWith e sp UnexpectedDescriptive msg + SDescriptive -> pure $ FromTyp t + +expr :: (V.HasEvaluation c) => ParserEnv -> Ntn -> IO (Judgment c) +expr e n = case n of + N.Ident name s -> pure $ fromSynN $ Variable.find s name + N.Juxt (N.Keyword "init" _) n -> do + t <- typ e n + fromSynD e (N.span n) (Initial.create (N.span n) t) + N.Juxt n0 n1 -> do + s <- syn e "target of elimination" n0 + fromSynN <$> elim e s n1 + N.Keyword "Set" _ -> pure $ fromTypN $ Universe.formation SetU + N.Keyword "Prop" _ -> pure $ fromTypN $ Universe.formation PropU + N.Keyword "Int" _ -> pure $ fromTypN $ Builtin.formation BuiltinInt + N.Keyword "String" _ -> pure $ fromTypN $ Builtin.formation BuiltinString + N.Infix arg n@(N.Keyword "->" _) body -> + fromTypN <$> (Function.formation (N.span n) <$> binder e arg <*> typ e body) + N.Infix arg n@(N.Keyword "=>" _) body -> + FromChk "lambda expression" + <$> (Function.intro (N.span n) <$> ident e arg <*> chk e body) + n@(N.Infix lhs (N.Keyword "=" _) rhs) -> + fromTypN + <$> ( Equality.formation (N.span n) + <$> syn e "term in equality" lhs + <*> syn e "term in equality" rhs + ) + N.Block "sig" Nothing ns _ -> do + t <- Record.formation <$> traverse (fieldDecl e) ns + fromTypD e (N.span n) t + N.Block "struct" Nothing ns s -> + FromChk "struct expression" <$> (Record.intro s <$> traverse (fieldSetting e) ns) + N.Int i _ -> pure $ fromSynN $ Builtin.intro $ LitInt i + N.String s _ -> pure $ fromSynN $ Builtin.intro $ LitString s + n -> unexpectedNotation e n "expression" + +syn :: (V.HasEvaluation c) => ParserEnv -> DDoc -> Ntn -> IO (Syn c) +syn e use n = intoSyn use (N.span n) <$> expr e n + +chk :: (V.HasEvaluation c) => ParserEnv -> Ntn -> IO (Chk c) +chk e n = intoChk (N.span n) <$> expr e n + +typ :: ParserEnv -> Ntn -> IO (Typ N) +typ e n = intoTyp (N.span n) <$> expr e n + +elim :: ParserEnv -> Syn N -> Ntn -> IO (Syn N) +elim e j = \case + N.Field x s -> pure $ Record.elim s j x + arg -> Function.elim (N.span arg) j <$> chk e arg diff --git a/packages/coln-compiler/src/Coln/Frontend/Parser/Top.hs b/packages/coln-compiler/src/Coln/Frontend/Parser/Top.hs new file mode 100644 index 00000000..3a241bb9 --- /dev/null +++ b/packages/coln-compiler/src/Coln/Frontend/Parser/Top.hs @@ -0,0 +1,134 @@ +-- SPDX-FileCopyrightText: 2026 Coln contributors +-- +-- SPDX-License-Identifier: Apache-2.0 OR MIT + +module Coln.Frontend.Parser.Top where + +import Control.Exception (try) +import Data.Foldable +import Data.Functor.Contravariant (contramap) +import Data.List.NonEmpty (NonEmpty (..)) +import FNotation (Ntn) +import FNotation qualified as N +import Prettyprinter + +import Coln.Common +import Coln.Core +import Coln.Core.Layout +import Coln.Core.Memoed qualified as M +import Coln.Core.Value qualified as V +import Coln.Diagnostics +import Coln.Elaborator.Environment +import Coln.Elaborator.Judgment +import Coln.Elaborator.Rules.Function qualified as Function +import Coln.Frontend.Diagnostics +import Coln.Frontend.Notation +import Coln.Frontend.Parser.Expr + +definition :: ParserEnv -> Ntn -> IO (Ntn, Ntn) +definition _ (N.Infix n0 (N.Keyword ":=" _) n1) = pure (n0, n1) +definition e n = unexpectedNotation e n "notation of the form ` := `" + +annot :: ParserEnv -> Ntn -> IO (Ntn, Ntn) +annot _ (N.Infix n0 (N.Keyword ":" _) n1) = pure (n0, n1) +annot e n = unexpectedNotation e n "type-annotated expression, e.g. ` : `" + +argBinding :: ParserEnv -> Ntn -> IO (Span, Mode, Name, Typ N) +argBinding e n@(N.Infix n0 (N.Keyword ":" _) n1) = do + (m, x) <- modalIdent e Conjunctive n0 + a <- typ e n1 + pure (N.span n, m, x, a) +argBinding e n = unexpectedNotation e n "argument binding of the form ` : `" + +unpackArgs :: ParserEnv -> Ntn -> IO (Name, [(Span, Mode, Name, Typ N)]) +unpackArgs e (N.Group (xN :| argsN)) = do + x <- ident e xN + args <- mapM (argBinding e) argsN + pure (x, args) + +withArgs :: (V.HasEvaluation c) => [(Span, Mode, Name, Typ N)] -> (Typ N, Chk c) -> (Typ N, Chk c) +withArgs args base = foldr go base args + where + go :: (V.HasEvaluation c) => (Span, Mode, Name, Typ N) -> (Typ N, Chk c) -> (Typ N, Chk c) + go (sp, m, name, a) (t, c) = + ( Function.formation sp (Function.Named m name a) t + , Function.intro sp name c + ) + +theory :: ParserEnv -> Ntn -> IO (Name, Typ N, Chk D) +theory e n = do + (pat_n, body_n) <- definition e n + (name, args) <- unpackArgs e pat_n + body <- chk e body_n + let (ty, tm) = withArgs args (Typ $ \_ -> pure $ M.univ TheoryU, body) + pure $ (name, ty, tm) + +def :: ParserEnv -> Ntn -> IO (Name, Typ N, Chk D) +def e n = do + (head_n, body_n) <- definition e n + (pat_n, ty_n) <- annot e head_n + (name, args) <- unpackArgs e pat_n + returnTyp <- typ e ty_n + body <- chk e body_n + let (ty, tm) = withArgs args (returnTyp, body) + pure (name, ty, tm) + +elabEntry :: DiagnosticEnv ElaboratorCode -> Globals -> Mode -> (Name, Typ N, Chk D) -> IO GlobalEntry +elabEntry e g m (x, ty, tm) = do + let tyE = emptyElabEnv e g m + a <- ty.elab tyE + let tmE = emptyElabEnvFor e g m x a.val + t <- tm.elab tmE a.val + let v = V.reflect (V.GlobalVar x v) V.Id a.val (Just t.val) + let entry = GlobalEntry t.stx v a.val m + pure entry + +realmHead :: ParserEnv -> Ntn -> IO (Name, Ntn) +realmHead _ (N.Infix (N.Ident x _) (N.Keyword "@" _) n) = pure (x, n) +realmHead e n = unexpectedNotation e n "realm head" + +realm :: DiagnosticEnv ColnCode -> Globals -> Ntn -> [Ntn] -> IO (Name, Realm) +realm e g head _defs = do + (x, theory_n) <- realmHead (contramap ParserCode e) head + theory_typ <- typ (contramap ParserCode e) theory_n + theory <- theory_typ.elab (emptyElabEnv (contramap ElaboratorCode e) g Inductive) + let (gt, root) = layoutTop x theory.val + pure (x, Realm gt root.val theory.val) + +mode :: ParserEnv -> Span -> [Name] -> IO Mode +mode _ _ [] = pure Conjunctive +mode _ _ ["ind"] = pure Inductive +mode e sp ms = do + let msg = "unknown modifiers" <+> hsep (dpretty <$> ms) + failWith e sp UnknownModifiers msg + +decl :: DiagnosticEnv ColnCode -> Globals -> Ntn -> IO Globals +decl e g (N.MDecl ms "theory" n sp) = do + m <- mode (contramap ParserCode e) sp ms + (x, t, c) <- theory (contramap ParserCode e) n + ge <- elabEntry (contramap ElaboratorCode e) g m (x, t, c) + pure $ addGlobalEntry x ge g +decl e g (N.MDecl ms "def" n sp) = do + m <- mode (contramap ParserCode e) sp ms + (x, t, c) <- def (contramap ParserCode e) n + ge <- elabEntry (contramap ElaboratorCode e) g m (x, t, c) + pure $ addGlobalEntry x ge g +decl e g (N.Block "realm" (Just head) body _) = do + (x, r) <- realm e g head body + pure $ addRealm x r g +decl e _ n = unexpectedNotation (contramap ParserCode e) n "top-level declaration" + +tryDecl :: DiagnosticEnv ColnCode -> Globals -> Ntn -> IO Globals +tryDecl e g n = do + try (decl e g n) >>= \case + Right g' -> pure g' + Left (_ :: FailException) -> pure g + +top :: DiagnosticEnv ColnCode -> [Ntn] -> IO Globals +top e = foldlM (tryDecl e) emptyGlobals + +topFromText :: Reporter ColnCode -> File -> IO Globals +topFromText r f = do + ts <- N.lex lexConfig (contramap LexerCode r) f + ns <- N.read readConfig (contramap ReaderCode r) f ts + top (DiagnosticEnv r f) ns diff --git a/packages/coln-compiler/test/Main.hs b/packages/coln-compiler/test/Main.hs index 713dc5f3..db88e930 100644 --- a/packages/coln-compiler/test/Main.hs +++ b/packages/coln-compiler/test/Main.hs @@ -49,9 +49,10 @@ render :: DDoc -> LBS.ByteString render = TLE.encodeUtf8 . renderLazy . layoutPretty defaultLayoutOptions prettyEntry :: (Name, GlobalEntry) -> DDoc -prettyEntry (x, (GlobalEntry t _ a)) = +prettyEntry (x, (GlobalEntry t _ a m)) = vsep [ "global entry named" <+> dpretty x + , "in mode:" <+> dpretty m , "type:" <+> prtIn (CtxShape 0 BwdNil) a , "value:" <+> dprettyWithNames mempty t ] diff --git a/packages/coln-compiler/test/golden/ancestor.output b/packages/coln-compiler/test/golden/ancestor.output index 81720679..c02f5cb4 100644 --- a/packages/coln-compiler/test/golden/ancestor.output +++ b/packages/coln-compiler/test/golden/ancestor.output @@ -1,5 +1,6 @@ -- elaborated global entry named Family +in mode: Conjunctive type: Theory value: sig person : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/builtin-root.output b/packages/coln-compiler/test/golden/basic-ir/builtin-root.output index ff6d8ac2..e7361b47 100644 --- a/packages/coln-compiler/test/golden/basic-ir/builtin-root.output +++ b/packages/coln-compiler/test/golden/basic-ir/builtin-root.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig count : Int diff --git a/packages/coln-compiler/test/golden/basic-ir/builtin.output b/packages/coln-compiler/test/golden/basic-ir/builtin.output index a12f33d8..a3869139 100644 --- a/packages/coln-compiler/test/golden/basic-ir/builtin.output +++ b/packages/coln-compiler/test/golden/basic-ir/builtin.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig V : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/empty-prop-record.output b/packages/coln-compiler/test/golden/basic-ir/empty-prop-record.output index 797dd05c..4890161d 100644 --- a/packages/coln-compiler/test/golden/basic-ir/empty-prop-record.output +++ b/packages/coln-compiler/test/golden/basic-ir/empty-prop-record.output @@ -1,9 +1,11 @@ -- elaborated global entry named Truth +in mode: Conjunctive type: Prop value: sig end global entry named T +in mode: Conjunctive type: Theory value: sig truth : Truth diff --git a/packages/coln-compiler/test/golden/basic-ir/empty-record.output b/packages/coln-compiler/test/golden/basic-ir/empty-record.output index f22be40e..c0c5b519 100644 --- a/packages/coln-compiler/test/golden/basic-ir/empty-record.output +++ b/packages/coln-compiler/test/golden/basic-ir/empty-record.output @@ -1,9 +1,11 @@ -- elaborated global entry named Unit +in mode: Conjunctive type: Set value: sig end global entry named T +in mode: Conjunctive type: Theory value: sig unit : Unit diff --git a/packages/coln-compiler/test/golden/basic-ir/empty-theory.output b/packages/coln-compiler/test/golden/basic-ir/empty-theory.output index 9b3bdce1..7bb1832e 100644 --- a/packages/coln-compiler/test/golden/basic-ir/empty-theory.output +++ b/packages/coln-compiler/test/golden/basic-ir/empty-theory.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig end diff --git a/packages/coln-compiler/test/golden/basic-ir/equality-prop.output b/packages/coln-compiler/test/golden/basic-ir/equality-prop.output index 978fcd5e..8cc6e1c4 100644 --- a/packages/coln-compiler/test/golden/basic-ir/equality-prop.output +++ b/packages/coln-compiler/test/golden/basic-ir/equality-prop.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig P : Prop diff --git a/packages/coln-compiler/test/golden/basic-ir/equality.output b/packages/coln-compiler/test/golden/basic-ir/equality.output index 63a31ab1..0c0586ac 100644 --- a/packages/coln-compiler/test/golden/basic-ir/equality.output +++ b/packages/coln-compiler/test/golden/basic-ir/equality.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig V : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/foreign-key-prop-prop.output b/packages/coln-compiler/test/golden/basic-ir/foreign-key-prop-prop.output index 86d11401..b0977e79 100644 --- a/packages/coln-compiler/test/golden/basic-ir/foreign-key-prop-prop.output +++ b/packages/coln-compiler/test/golden/basic-ir/foreign-key-prop-prop.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig V : Prop diff --git a/packages/coln-compiler/test/golden/basic-ir/foreign-key-prop-set.output b/packages/coln-compiler/test/golden/basic-ir/foreign-key-prop-set.output index 79b5d018..982cd26b 100644 --- a/packages/coln-compiler/test/golden/basic-ir/foreign-key-prop-set.output +++ b/packages/coln-compiler/test/golden/basic-ir/foreign-key-prop-set.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig V : Prop diff --git a/packages/coln-compiler/test/golden/basic-ir/foreign-key-set-prop.output b/packages/coln-compiler/test/golden/basic-ir/foreign-key-set-prop.output index f6042360..ccfae4b4 100644 --- a/packages/coln-compiler/test/golden/basic-ir/foreign-key-set-prop.output +++ b/packages/coln-compiler/test/golden/basic-ir/foreign-key-set-prop.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig V : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/foreign-key.output b/packages/coln-compiler/test/golden/basic-ir/foreign-key.output index f5b93506..3db52628 100644 --- a/packages/coln-compiler/test/golden/basic-ir/foreign-key.output +++ b/packages/coln-compiler/test/golden/basic-ir/foreign-key.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig V : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/function-mixed-prop-set.output b/packages/coln-compiler/test/golden/basic-ir/function-mixed-prop-set.output index 15cf11c3..7b209e87 100644 --- a/packages/coln-compiler/test/golden/basic-ir/function-mixed-prop-set.output +++ b/packages/coln-compiler/test/golden/basic-ir/function-mixed-prop-set.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig X : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/function-multi-argument.output b/packages/coln-compiler/test/golden/basic-ir/function-multi-argument.output index f870d9ec..2b424006 100644 --- a/packages/coln-compiler/test/golden/basic-ir/function-multi-argument.output +++ b/packages/coln-compiler/test/golden/basic-ir/function-multi-argument.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig X : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/function-prop-prop.output b/packages/coln-compiler/test/golden/basic-ir/function-prop-prop.output index 78462a24..c10c115c 100644 --- a/packages/coln-compiler/test/golden/basic-ir/function-prop-prop.output +++ b/packages/coln-compiler/test/golden/basic-ir/function-prop-prop.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig X : Prop diff --git a/packages/coln-compiler/test/golden/basic-ir/function-prop-set.output b/packages/coln-compiler/test/golden/basic-ir/function-prop-set.output index bf875d89..9dc2aa9e 100644 --- a/packages/coln-compiler/test/golden/basic-ir/function-prop-set.output +++ b/packages/coln-compiler/test/golden/basic-ir/function-prop-set.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig X : Prop diff --git a/packages/coln-compiler/test/golden/basic-ir/function-set-prop.output b/packages/coln-compiler/test/golden/basic-ir/function-set-prop.output index 3cd5ce06..75659a87 100644 --- a/packages/coln-compiler/test/golden/basic-ir/function-set-prop.output +++ b/packages/coln-compiler/test/golden/basic-ir/function-set-prop.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig X : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/function.output b/packages/coln-compiler/test/golden/basic-ir/function.output index 0d46eb77..94516841 100644 --- a/packages/coln-compiler/test/golden/basic-ir/function.output +++ b/packages/coln-compiler/test/golden/basic-ir/function.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig X : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/lookup-builtin.output b/packages/coln-compiler/test/golden/basic-ir/lookup-builtin.output index e4b33221..cd18a07c 100644 --- a/packages/coln-compiler/test/golden/basic-ir/lookup-builtin.output +++ b/packages/coln-compiler/test/golden/basic-ir/lookup-builtin.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig X : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/lookup-composition-prop.output b/packages/coln-compiler/test/golden/basic-ir/lookup-composition-prop.output index ceec7b16..c3ff7136 100644 --- a/packages/coln-compiler/test/golden/basic-ir/lookup-composition-prop.output +++ b/packages/coln-compiler/test/golden/basic-ir/lookup-composition-prop.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig A : Prop diff --git a/packages/coln-compiler/test/golden/basic-ir/lookup-composition.output b/packages/coln-compiler/test/golden/basic-ir/lookup-composition.output index ede8104b..58b20987 100644 --- a/packages/coln-compiler/test/golden/basic-ir/lookup-composition.output +++ b/packages/coln-compiler/test/golden/basic-ir/lookup-composition.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig A : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/lookup-literal-prop.output b/packages/coln-compiler/test/golden/basic-ir/lookup-literal-prop.output index fc668834..11ca4a26 100644 --- a/packages/coln-compiler/test/golden/basic-ir/lookup-literal-prop.output +++ b/packages/coln-compiler/test/golden/basic-ir/lookup-literal-prop.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig IntFact : Int -> Prop diff --git a/packages/coln-compiler/test/golden/basic-ir/lookup-literal.output b/packages/coln-compiler/test/golden/basic-ir/lookup-literal.output index 53a8a6e8..a46dff39 100644 --- a/packages/coln-compiler/test/golden/basic-ir/lookup-literal.output +++ b/packages/coln-compiler/test/golden/basic-ir/lookup-literal.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig IntEdge : Int -> Set diff --git a/packages/coln-compiler/test/golden/basic-ir/lookup-projection-prop-prop-prop.output b/packages/coln-compiler/test/golden/basic-ir/lookup-projection-prop-prop-prop.output index 7e1d98a3..e8bf3176 100644 --- a/packages/coln-compiler/test/golden/basic-ir/lookup-projection-prop-prop-prop.output +++ b/packages/coln-compiler/test/golden/basic-ir/lookup-projection-prop-prop-prop.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig A : Prop diff --git a/packages/coln-compiler/test/golden/basic-ir/lookup-projection-prop-prop-set.output b/packages/coln-compiler/test/golden/basic-ir/lookup-projection-prop-prop-set.output index 8b099309..f355b95b 100644 --- a/packages/coln-compiler/test/golden/basic-ir/lookup-projection-prop-prop-set.output +++ b/packages/coln-compiler/test/golden/basic-ir/lookup-projection-prop-prop-set.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig A : Prop diff --git a/packages/coln-compiler/test/golden/basic-ir/lookup-projection-prop-set-prop.output b/packages/coln-compiler/test/golden/basic-ir/lookup-projection-prop-set-prop.output index 2423f783..481b16fd 100644 --- a/packages/coln-compiler/test/golden/basic-ir/lookup-projection-prop-set-prop.output +++ b/packages/coln-compiler/test/golden/basic-ir/lookup-projection-prop-set-prop.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig A : Prop diff --git a/packages/coln-compiler/test/golden/basic-ir/lookup-projection-prop-set-set.output b/packages/coln-compiler/test/golden/basic-ir/lookup-projection-prop-set-set.output index 59dc0dd5..9cc681da 100644 --- a/packages/coln-compiler/test/golden/basic-ir/lookup-projection-prop-set-set.output +++ b/packages/coln-compiler/test/golden/basic-ir/lookup-projection-prop-set-set.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig A : Prop diff --git a/packages/coln-compiler/test/golden/basic-ir/lookup-projection-set-prop-prop.output b/packages/coln-compiler/test/golden/basic-ir/lookup-projection-set-prop-prop.output index 565b5a6b..eddc419e 100644 --- a/packages/coln-compiler/test/golden/basic-ir/lookup-projection-set-prop-prop.output +++ b/packages/coln-compiler/test/golden/basic-ir/lookup-projection-set-prop-prop.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig A : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/lookup-projection-set-prop-set.output b/packages/coln-compiler/test/golden/basic-ir/lookup-projection-set-prop-set.output index ba638feb..f92c6586 100644 --- a/packages/coln-compiler/test/golden/basic-ir/lookup-projection-set-prop-set.output +++ b/packages/coln-compiler/test/golden/basic-ir/lookup-projection-set-prop-set.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig A : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/lookup-projection-set-set-prop.output b/packages/coln-compiler/test/golden/basic-ir/lookup-projection-set-set-prop.output index 9e4137e2..01e37dc6 100644 --- a/packages/coln-compiler/test/golden/basic-ir/lookup-projection-set-set-prop.output +++ b/packages/coln-compiler/test/golden/basic-ir/lookup-projection-set-set-prop.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig A : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/lookup-projection.output b/packages/coln-compiler/test/golden/basic-ir/lookup-projection.output index 31f12076..412d60c6 100644 --- a/packages/coln-compiler/test/golden/basic-ir/lookup-projection.output +++ b/packages/coln-compiler/test/golden/basic-ir/lookup-projection.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig A : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/lookup-record-composition.output b/packages/coln-compiler/test/golden/basic-ir/lookup-record-composition.output index afc5c9fb..a38f6a85 100644 --- a/packages/coln-compiler/test/golden/basic-ir/lookup-record-composition.output +++ b/packages/coln-compiler/test/golden/basic-ir/lookup-record-composition.output @@ -1,15 +1,18 @@ -- elaborated global entry named Key +in mode: Conjunctive type: Set value: sig rank : Int end global entry named Payload +in mode: Conjunctive type: Set value: sig name : String end global entry named T +in mode: Conjunctive type: Theory value: sig X : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/lookup-record-expansion.output b/packages/coln-compiler/test/golden/basic-ir/lookup-record-expansion.output index f87ded8b..bf60c3c2 100644 --- a/packages/coln-compiler/test/golden/basic-ir/lookup-record-expansion.output +++ b/packages/coln-compiler/test/golden/basic-ir/lookup-record-expansion.output @@ -1,11 +1,13 @@ -- elaborated global entry named Payload +in mode: Conjunctive type: Set value: sig name : String rank : Int end global entry named T +in mode: Conjunctive type: Theory value: sig X : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/lookup-record-field.output b/packages/coln-compiler/test/golden/basic-ir/lookup-record-field.output index 5da48038..c709f749 100644 --- a/packages/coln-compiler/test/golden/basic-ir/lookup-record-field.output +++ b/packages/coln-compiler/test/golden/basic-ir/lookup-record-field.output @@ -1,11 +1,13 @@ -- elaborated global entry named Payload +in mode: Conjunctive type: Set value: sig name : String rank : Int end global entry named T +in mode: Conjunctive type: Theory value: sig X : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/lookup-record.output b/packages/coln-compiler/test/golden/basic-ir/lookup-record.output index 39e28cb6..343bc716 100644 --- a/packages/coln-compiler/test/golden/basic-ir/lookup-record.output +++ b/packages/coln-compiler/test/golden/basic-ir/lookup-record.output @@ -1,14 +1,17 @@ -- elaborated global entry named Payload +in mode: Conjunctive type: Set value: sig name : String rank : Int end global entry named fixed +in mode: Conjunctive type: Payload value: [name := "fixed", rank := 1] global entry named T +in mode: Conjunctive type: Theory value: sig E : Payload -> Set diff --git a/packages/coln-compiler/test/golden/basic-ir/param-record-concrete.output b/packages/coln-compiler/test/golden/basic-ir/param-record-concrete.output index 2ca90fd4..5e902b42 100644 --- a/packages/coln-compiler/test/golden/basic-ir/param-record-concrete.output +++ b/packages/coln-compiler/test/golden/basic-ir/param-record-concrete.output @@ -1,15 +1,18 @@ -- elaborated global entry named Payload +in mode: Conjunctive type: Set value: sig name : String end global entry named Box +in mode: Conjunctive type: (X : Set) -> Set value: X => sig value : X end global entry named T +in mode: Conjunctive type: Theory value: sig boxed : Box Payload -> Set diff --git a/packages/coln-compiler/test/golden/basic-ir/param-record-model.output b/packages/coln-compiler/test/golden/basic-ir/param-record-model.output index 0f4b510f..dfb83e32 100644 --- a/packages/coln-compiler/test/golden/basic-ir/param-record-model.output +++ b/packages/coln-compiler/test/golden/basic-ir/param-record-model.output @@ -1,21 +1,25 @@ -- elaborated global entry named Model +in mode: Conjunctive type: Theory value: sig X : Set end global entry named Payload +in mode: Conjunctive type: Set value: sig name : String end global entry named Box +in mode: Conjunctive type: (M : Model) -> (Y : Set) -> Set value: M => Y => sig modelValue : M.X value : Y end global entry named T +in mode: Conjunctive type: Theory value: sig model : Model diff --git a/packages/coln-compiler/test/golden/basic-ir/param-record-nested.output b/packages/coln-compiler/test/golden/basic-ir/param-record-nested.output index 43af4248..9de21eae 100644 --- a/packages/coln-compiler/test/golden/basic-ir/param-record-nested.output +++ b/packages/coln-compiler/test/golden/basic-ir/param-record-nested.output @@ -1,16 +1,19 @@ -- elaborated global entry named Box +in mode: Conjunctive type: (X : Set) -> Set value: X => sig value : X end global entry named Nested +in mode: Conjunctive type: (X : Set) -> Set value: X => sig inner : Box X sibling : X end global entry named T +in mode: Conjunctive type: Theory value: sig X : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/param-record.output b/packages/coln-compiler/test/golden/basic-ir/param-record.output index 1fd96246..e0234631 100644 --- a/packages/coln-compiler/test/golden/basic-ir/param-record.output +++ b/packages/coln-compiler/test/golden/basic-ir/param-record.output @@ -1,10 +1,12 @@ -- elaborated global entry named Box +in mode: Conjunctive type: (X : Set) -> Set value: X => sig value : X end global entry named T +in mode: Conjunctive type: Theory value: sig X : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/param-theory-model.output b/packages/coln-compiler/test/golden/basic-ir/param-theory-model.output index a3e83bf5..50f9933d 100644 --- a/packages/coln-compiler/test/golden/basic-ir/param-theory-model.output +++ b/packages/coln-compiler/test/golden/basic-ir/param-theory-model.output @@ -1,15 +1,18 @@ -- elaborated global entry named Model +in mode: Conjunctive type: Theory value: sig X : Set end global entry named PointOf +in mode: Conjunctive type: (M : Model) -> Theory value: M => sig point : M.X end global entry named T +in mode: Conjunctive type: Theory value: sig model : Model diff --git a/packages/coln-compiler/test/golden/basic-ir/param-theory-nested.output b/packages/coln-compiler/test/golden/basic-ir/param-theory-nested.output index 9cbece3f..6df8abd0 100644 --- a/packages/coln-compiler/test/golden/basic-ir/param-theory-nested.output +++ b/packages/coln-compiler/test/golden/basic-ir/param-theory-nested.output @@ -1,15 +1,18 @@ -- elaborated global entry named PointOf +in mode: Conjunctive type: (X : Set) -> Theory value: X => sig point : X end global entry named Pointed +in mode: Conjunctive type: (X : Set) -> Theory value: X => sig inner : PointOf X end global entry named T +in mode: Conjunctive type: Theory value: sig X : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/param-theory.output b/packages/coln-compiler/test/golden/basic-ir/param-theory.output index fc890cbc..f16fc075 100644 --- a/packages/coln-compiler/test/golden/basic-ir/param-theory.output +++ b/packages/coln-compiler/test/golden/basic-ir/param-theory.output @@ -1,10 +1,12 @@ -- elaborated global entry named PointOf +in mode: Conjunctive type: (X : Set) -> Theory value: X => sig point : X end global entry named T +in mode: Conjunctive type: Theory value: sig X : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/projection.output b/packages/coln-compiler/test/golden/basic-ir/projection.output index e7ec4a1e..7fb6bbd7 100644 --- a/packages/coln-compiler/test/golden/basic-ir/projection.output +++ b/packages/coln-compiler/test/golden/basic-ir/projection.output @@ -1,11 +1,13 @@ -- elaborated global entry named Payload +in mode: Conjunctive type: (X : Set) -> Set value: X => sig first : X second : X end global entry named T +in mode: Conjunctive type: Theory value: sig X : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/proof-record-mixed.output b/packages/coln-compiler/test/golden/basic-ir/proof-record-mixed.output index 240caa01..1db84b7f 100644 --- a/packages/coln-compiler/test/golden/basic-ir/proof-record-mixed.output +++ b/packages/coln-compiler/test/golden/basic-ir/proof-record-mixed.output @@ -1,5 +1,6 @@ -- elaborated global entry named EqualTriple +in mode: Conjunctive type: (X : Set) -> Set value: X => sig first : X @@ -8,6 +9,7 @@ value: X => sig trailing : X end global entry named T +in mode: Conjunctive type: Theory value: sig X : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/proof-record-parameter.output b/packages/coln-compiler/test/golden/basic-ir/proof-record-parameter.output index 82de7ce1..ca155bc8 100644 --- a/packages/coln-compiler/test/golden/basic-ir/proof-record-parameter.output +++ b/packages/coln-compiler/test/golden/basic-ir/proof-record-parameter.output @@ -1,5 +1,6 @@ -- elaborated global entry named EqualTriple +in mode: Conjunctive type: (X : Set) -> Set value: X => sig first : X @@ -8,6 +9,7 @@ value: X => sig trailing : X end global entry named T +in mode: Conjunctive type: Theory value: sig X : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/proof-record.coln b/packages/coln-compiler/test/golden/basic-ir/proof-record.coln index 89844234..3ac8728f 100644 --- a/packages/coln-compiler/test/golden/basic-ir/proof-record.coln +++ b/packages/coln-compiler/test/golden/basic-ir/proof-record.coln @@ -4,7 +4,7 @@ end theory T := sig X : Set - witness : (x : X) -> Witness X x + witness : (^c x : X) -> Witness X x end realm TRealm @ T diff --git a/packages/coln-compiler/test/golden/basic-ir/proof-record.output b/packages/coln-compiler/test/golden/basic-ir/proof-record.output index bbe47ee9..d0be92b4 100644 --- a/packages/coln-compiler/test/golden/basic-ir/proof-record.output +++ b/packages/coln-compiler/test/golden/basic-ir/proof-record.output @@ -1,10 +1,12 @@ -- elaborated global entry named Witness +in mode: Conjunctive type: (X : Set) -> (x : X) -> Set value: X => x => sig proof : x = x end global entry named T +in mode: Conjunctive type: Theory value: sig X : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/prop-multi-argument.output b/packages/coln-compiler/test/golden/basic-ir/prop-multi-argument.output index 2c0df80e..9b51f62a 100644 --- a/packages/coln-compiler/test/golden/basic-ir/prop-multi-argument.output +++ b/packages/coln-compiler/test/golden/basic-ir/prop-multi-argument.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig X : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/prop-record.output b/packages/coln-compiler/test/golden/basic-ir/prop-record.output index 0b1afcb4..26c83c86 100644 --- a/packages/coln-compiler/test/golden/basic-ir/prop-record.output +++ b/packages/coln-compiler/test/golden/basic-ir/prop-record.output @@ -1,11 +1,13 @@ -- elaborated global entry named And +in mode: Conjunctive type: (P : Prop) -> (Q : Prop) -> Prop value: P => Q => sig left : P right : Q end global entry named T +in mode: Conjunctive type: Theory value: sig P : Prop diff --git a/packages/coln-compiler/test/golden/basic-ir/prop.output b/packages/coln-compiler/test/golden/basic-ir/prop.output index e54fbb16..00286c00 100644 --- a/packages/coln-compiler/test/golden/basic-ir/prop.output +++ b/packages/coln-compiler/test/golden/basic-ir/prop.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig V : Prop diff --git a/packages/coln-compiler/test/golden/basic-ir/record-field-order.output b/packages/coln-compiler/test/golden/basic-ir/record-field-order.output index c2db09cf..776f7187 100644 --- a/packages/coln-compiler/test/golden/basic-ir/record-field-order.output +++ b/packages/coln-compiler/test/golden/basic-ir/record-field-order.output @@ -1,11 +1,13 @@ -- elaborated global entry named Pair +in mode: Conjunctive type: Set value: sig first : Int second : Int end global entry named T +in mode: Conjunctive type: Theory value: sig E : Int -> Int -> Set diff --git a/packages/coln-compiler/test/golden/basic-ir/record.output b/packages/coln-compiler/test/golden/basic-ir/record.output index 5b1ea068..ee5e7338 100644 --- a/packages/coln-compiler/test/golden/basic-ir/record.output +++ b/packages/coln-compiler/test/golden/basic-ir/record.output @@ -1,11 +1,13 @@ -- elaborated global entry named Payload +in mode: Conjunctive type: Set value: sig name : String rank : Int end global entry named T +in mode: Conjunctive type: Theory value: sig point : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/repeated-binders.output b/packages/coln-compiler/test/golden/basic-ir/repeated-binders.output index ed5d0ee0..08a33de8 100644 --- a/packages/coln-compiler/test/golden/basic-ir/repeated-binders.output +++ b/packages/coln-compiler/test/golden/basic-ir/repeated-binders.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig X : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/rule-literals.output b/packages/coln-compiler/test/golden/basic-ir/rule-literals.output index 30ac2203..7b2ad8a5 100644 --- a/packages/coln-compiler/test/golden/basic-ir/rule-literals.output +++ b/packages/coln-compiler/test/golden/basic-ir/rule-literals.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig X : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/set.output b/packages/coln-compiler/test/golden/basic-ir/set.output index 02750de5..b7a9cccb 100644 --- a/packages/coln-compiler/test/golden/basic-ir/set.output +++ b/packages/coln-compiler/test/golden/basic-ir/set.output @@ -1,5 +1,6 @@ -- elaborated global entry named T +in mode: Conjunctive type: Theory value: sig V : Set diff --git a/packages/coln-compiler/test/golden/basic-ir/theory-alias.output b/packages/coln-compiler/test/golden/basic-ir/theory-alias.output index bbaa0e75..a4b174a1 100644 --- a/packages/coln-compiler/test/golden/basic-ir/theory-alias.output +++ b/packages/coln-compiler/test/golden/basic-ir/theory-alias.output @@ -1,10 +1,12 @@ -- elaborated global entry named Base +in mode: Conjunctive type: Theory value: sig X : Set end global entry named Alias +in mode: Conjunctive type: Theory value: Base realm named TRealm diff --git a/packages/coln-compiler/test/golden/elaborator-errors.output b/packages/coln-compiler/test/golden/elaborator-errors.output index 89a00509..ed36d1c0 100644 --- a/packages/coln-compiler/test/golden/elaborator-errors.output +++ b/packages/coln-compiler/test/golden/elaborator-errors.output @@ -1,31 +1,37 @@ -- elaborated global entry named Pair +in mode: Conjunctive type: Set value: sig first : Int second : Int end global entry named pair +in mode: Conjunctive type: Pair value: [first := 1, second := 2] global entry named Dependent +in mode: Conjunctive type: Theory value: sig A : Set value : A end global entry named dependent +in mode: Conjunctive type: Dependent value: [A := Int, value := 1] -global entry named identity -type: Int -> Int -value: x => x -global entry named shadow -type: (x : String) -> Int -> Int -value: x => x => x -- messages +error[E0316]: cannot use inductively bound variable in a conjunctive context +21 | def identity : Int -> Int := x => x +21 | ^ + +error[E0316]: cannot use inductively bound variable in a conjunctive context +23 | def shadow (x : String) : Int -> Int := x => x +23 | ^ + error[E0302]: tried to project from a value that was not of a record type 25 | def projectionOfNonRecord : Int := (1).missing 25 | ^^^^^^^^ diff --git a/packages/coln-compiler/test/golden/equality.coln b/packages/coln-compiler/test/golden/equality.coln new file mode 100644 index 00000000..118bc1f7 --- /dev/null +++ b/packages/coln-compiler/test/golden/equality.coln @@ -0,0 +1,6 @@ +theory ReflexiveRelation (^i X : Set) := sig + rel : (^i x : X) -> (^i y : X) -> Prop + refl : (^i x : X) -> rel x x +end + +ind def Eq (X : Set) : ReflexiveRelation X := init (ReflexiveRelation X) diff --git a/packages/coln-compiler/test/golden/equality.output b/packages/coln-compiler/test/golden/equality.output new file mode 100644 index 00000000..0826d3f6 --- /dev/null +++ b/packages/coln-compiler/test/golden/equality.output @@ -0,0 +1,14 @@ +-- elaborated +global entry named ReflexiveRelation +in mode: Conjunctive +type: (X : Set) -> Theory +value: X => sig + rel : (x : X) -> (y : X) -> Prop + refl : (x : X) -> rel x x +end +global entry named Eq +in mode: Inductive +type: (X : Set) -> ReflexiveRelation X +value: X => init (ReflexiveRelation X) + +-- messages diff --git a/packages/coln-compiler/test/golden/fb3.output b/packages/coln-compiler/test/golden/fb3.output index 168a03b6..7d714b29 100644 --- a/packages/coln-compiler/test/golden/fb3.output +++ b/packages/coln-compiler/test/golden/fb3.output @@ -1,11 +1,8 @@ -- elaborated -global entry named IdempotentSemigroup -type: Theory -value: sig - Element : Set - mul : (x : Element) -> (y : Element) -> Element - mul/idempotent : (x : Element) -> mul x x = x - mul/assoc : (x : Element) -> (y : Element) -> (z : Element) -> mul (mul x y) z = mul x (mul y z) -end + -- messages + +error[E0316]: cannot use inductively bound variable in a conjunctive context +7 | mul/idempotent : (x : Element) -> mul x x = x +7 | ^ diff --git a/packages/coln-compiler/test/golden/graph-of-graphs.output b/packages/coln-compiler/test/golden/graph-of-graphs.output index 7c1c670c..63d1ce8d 100644 --- a/packages/coln-compiler/test/golden/graph-of-graphs.output +++ b/packages/coln-compiler/test/golden/graph-of-graphs.output @@ -1,17 +1,20 @@ -- elaborated global entry named Graph +in mode: Conjunctive type: Theory value: sig V : Set E : V -> V -> Set end global entry named Graph/hom +in mode: Conjunctive type: (G0 : Graph) -> (G1 : Graph) -> Theory value: G0 => G1 => sig V : G0.V -> G1.V E : (v0 : G0.V) -> (v1 : G0.V) -> G0.E v0 v1 -> G1.E (V v0) (V v1) end global entry named GraphOfGraphs +in mode: Conjunctive type: Theory value: sig base : Graph diff --git a/packages/coln-compiler/test/golden/graph.output b/packages/coln-compiler/test/golden/graph.output index 960be3c5..048dac1b 100644 --- a/packages/coln-compiler/test/golden/graph.output +++ b/packages/coln-compiler/test/golden/graph.output @@ -1,5 +1,6 @@ -- elaborated global entry named Graph +in mode: Conjunctive type: Theory value: sig V : Set diff --git a/packages/coln-compiler/test/golden/hlevel.output b/packages/coln-compiler/test/golden/hlevel.output index 9325a41b..80e29d42 100644 --- a/packages/coln-compiler/test/golden/hlevel.output +++ b/packages/coln-compiler/test/golden/hlevel.output @@ -1,5 +1,6 @@ -- elaborated global entry named Family +in mode: Conjunctive type: Theory value: sig person : Set @@ -7,12 +8,14 @@ value: sig happy : Prop end global entry named Q +in mode: Conjunctive type: (F : Family) -> Theory value: F => sig son : F.person father : F.person end global entry named HP +in mode: Conjunctive type: Theory value: sig person : Set @@ -21,10 +24,12 @@ value: sig reveal : voldemort = tomriddle end global entry named Unit +in mode: Conjunctive type: Prop value: sig end global entry named P +in mode: Conjunctive type: Theory value: sig u : Unit diff --git a/packages/coln-compiler/test/golden/ind.coln b/packages/coln-compiler/test/golden/ind.coln new file mode 100644 index 00000000..01b70216 --- /dev/null +++ b/packages/coln-compiler/test/golden/ind.coln @@ -0,0 +1,14 @@ +theory Graph := sig + v : Set + e : v -> v -> Prop +end + +theory TransitiveExt (^i G : Graph) := sig + p : G.v -> G.v -> Prop + incl : (v0 : G.v) -> (v1 : G.v) -> G.e v0 v1 -> p v0 v1 + snoc : (v0 : G.v) -> (v1 : G.v) -> (v2 : G.v) -> p v0 v1 -> G.e v1 v2 -> p v0 v2 +end + +ind def transitive-closure (G : Graph) : TransitiveExt G := init (TransitiveExt G) + +ind def free-point (X : Set) : X := init X diff --git a/packages/coln-compiler/test/golden/ind.output b/packages/coln-compiler/test/golden/ind.output new file mode 100644 index 00000000..28758444 --- /dev/null +++ b/packages/coln-compiler/test/golden/ind.output @@ -0,0 +1,26 @@ +-- elaborated +global entry named Graph +in mode: Conjunctive +type: Theory +value: sig + v : Set + e : v -> v -> Prop +end +global entry named TransitiveExt +in mode: Conjunctive +type: (G : Graph) -> Theory +value: G => sig + p : G.v -> G.v -> Prop + incl : (v0 : G.v) -> (v1 : G.v) -> G.e v0 v1 -> p v0 v1 + snoc : (v0 : G.v) -> (v1 : G.v) -> (v2 : G.v) -> p v0 v1 -> G.e v1 v2 -> p v0 v2 +end +global entry named transitive-closure +in mode: Inductive +type: (G : Graph) -> TransitiveExt G +value: G => init (TransitiveExt G) + +-- messages + +error[E0316]: cannot use inductively bound variable in a conjunctive context +14 | ind def free-point (X : Set) : X := init X +14 | ^ diff --git a/packages/coln-compiler/test/golden/lambda.output b/packages/coln-compiler/test/golden/lambda.output index 3a944b8a..3521afb3 100644 --- a/packages/coln-compiler/test/golden/lambda.output +++ b/packages/coln-compiler/test/golden/lambda.output @@ -1,5 +1,6 @@ -- elaborated global entry named Lambda +in mode: Conjunctive type: Theory value: sig con : Set diff --git a/packages/coln-compiler/test/golden/magma.output b/packages/coln-compiler/test/golden/magma.output index 5f8fc089..273ebd56 100644 --- a/packages/coln-compiler/test/golden/magma.output +++ b/packages/coln-compiler/test/golden/magma.output @@ -1,5 +1,6 @@ -- elaborated global entry named Magma +in mode: Conjunctive type: Theory value: sig car : Set diff --git a/packages/coln-compiler/test/golden/modular-lattice.output b/packages/coln-compiler/test/golden/modular-lattice.output index add4021f..d77628e3 100644 --- a/packages/coln-compiler/test/golden/modular-lattice.output +++ b/packages/coln-compiler/test/golden/modular-lattice.output @@ -1,23 +1,12 @@ -- elaborated -global entry named ModularLattice -type: Theory -value: sig - Element : Set - meet : Element -> Element -> Element - meet/associative : (a : Element) -> (b : Element) -> (c : Element) -> meet (meet a b) c = meet a (meet b c) - meet/commutative : (a : Element) -> (b : Element) -> meet a b = meet b a - meet/idempotent : (a : Element) -> meet a a = a - join : Element -> Element -> Element - join/associative : (a : Element) -> (b : Element) -> (c : Element) -> join (join a b) c = join a (join b c) - join/associative : (a : Element) -> (b : Element) -> join a b = join b a - join/idempotent : (a : Element) -> join a a = a - ax/absorptive1 : (a : Element) -> (b : Element) -> meet a (join a b) = a - ax/absorptive2 : (a : Element) -> (b : Element) -> join a (meet a b) = a - ax/modular : (a : Element) -> (b : Element) -> (x : Element) -> join (meet a b) (meet x b) = meet (join (meet a b) x) b -end + -- messages +error[E0316]: cannot use inductively bound variable in a conjunctive context +17 | meet a a = a +17 | ^ + error[E0200]: unexpected notation for field setting of the form ` := `: Infix 49 | bot : Element 49 | ^^^^^^^^^^^^^ diff --git a/packages/coln-compiler/test/golden/monoid-glog.output b/packages/coln-compiler/test/golden/monoid-glog.output index 808c3322..83ab7ebc 100644 --- a/packages/coln-compiler/test/golden/monoid-glog.output +++ b/packages/coln-compiler/test/golden/monoid-glog.output @@ -1,13 +1,8 @@ -- elaborated -global entry named Monoid -type: Theory -value: sig - car : Set - unit : car - mul : car -> car -> car - mul/unitl : (x : car) -> mul unit x = x - mul/unitr : (x : car) -> mul x unit = x - mul/assoc : (x : car) -> (y : car) -> (z : car) -> mul (mul x y) z = mul x (mul y z) -end + -- messages + +error[E0316]: cannot use inductively bound variable in a conjunctive context +6 | mul/unitl : (x : car) -> mul unit x = x +6 | ^ diff --git a/packages/coln-compiler/test/golden/nominal.output b/packages/coln-compiler/test/golden/nominal.output index 9ef78e08..cc083644 100644 --- a/packages/coln-compiler/test/golden/nominal.output +++ b/packages/coln-compiler/test/golden/nominal.output @@ -1,13 +1,16 @@ -- elaborated global entry named A +in mode: Conjunctive type: Theory value: sig end global entry named B +in mode: Conjunctive type: Theory value: sig end global entry named a +in mode: Conjunctive type: A value: [] diff --git a/packages/coln-compiler/test/golden/paths.coln b/packages/coln-compiler/test/golden/paths.coln index 75c44239..d5fb01ec 100644 --- a/packages/coln-compiler/test/golden/paths.coln +++ b/packages/coln-compiler/test/golden/paths.coln @@ -16,6 +16,8 @@ theory Reachability/motive (G : Graph) := sig ) end + + realm Graph @ Graph ind def reachability : Reachability/motive self := init (Reachability/motive self) end diff --git a/packages/coln-compiler/test/golden/paths.output b/packages/coln-compiler/test/golden/paths.output index a3ee8f95..24701861 100644 --- a/packages/coln-compiler/test/golden/paths.output +++ b/packages/coln-compiler/test/golden/paths.output @@ -1,26 +1,36 @@ -- elaborated global entry named Graph +in mode: Conjunctive type: Theory value: sig V : Set E : V -> V -> Prop end global entry named Reachability/motive +in mode: Conjunctive type: (G : Graph) -> Theory value: G => sig t : G.V -> G.V -> Prop empty : (x : G.V) -> t x x cons : (x : G.V) -> (y : G.V) -> (z : G.V) -> (e : G.E x y) -> t y z -> t x z end +realm named Graph +generators: node + V = rel [] + E = rel [a : Graph.V [], b : Graph.V []] +end +lowered: flatrealm + entities + table ℜ.V := [] + table ℜ.E := [.a : ℜ.V, .b : ℜ.V] + end + rules + enforced ℜ.V.foreignKey := ℜ.V [] ⊢ ⊤ + enforced ℜ.E.foreignKey a b := ℜ.E [ + .a ↦ a, + .b ↦ b + ] ⊢ a ∈ ℜ.V [] ∧ b ∈ ℜ.V [] + end +end -- messages - -error[E0104]: expected a newline, end, or eof after a statement -20 | ind def reachability : Reachability/motive self := init (Reachability/motive self) -20 | ^^^ - -error[E0200]: unexpected notation for top-level declaration: Infix -19 | realm Graph @ Graph -19 | ^^^^^^^^^^^^^^^^^^^ -20 | ind def reachability : Reachability/motive self := init (Reachability/motive self) -20 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/packages/coln-compiler/test/golden/ssa.output b/packages/coln-compiler/test/golden/ssa.output index 46a54dae..e6c60421 100644 --- a/packages/coln-compiler/test/golden/ssa.output +++ b/packages/coln-compiler/test/golden/ssa.output @@ -1,69 +1,46 @@ -- elaborated global entry named IsTransClosure +in mode: Conjunctive type: (X : Set) -> (R : X -> X -> Set) -> (P : X -> X -> Set) -> Theory value: X => R => P => sig refl : (x : X) -> P x x snoc : (x : X) -> (y : X) -> (z : X) -> P x y -> R y z -> P x z end -global entry named LinearOrder -type: Theory -value: sig - car : Set - first : car - last : car - next : car -> car - prev : car -> car - next/prev : (x : car) -> next (prev x) = x - prev/next : (x : car) -> prev (next x) = x - follows : car -> car -> Set - follows/is-trans-closure : IsTransClosure car (x => y => next x = y) follows - acyclic : (x : car) -> (y : car) -> follows x y -> follows y x -> x = y - first-is-top : (x : car) -> follows first x - last-is-bot : (x : car) -> follows x last -end global entry named OpInfo +in mode: Conjunctive type: Theory value: sig OpType : Set inputArity : OpType -> Set outputArity : OpType -> Set end -global entry named Iso -type: (A : Set) -> (B : Set) -> Theory -value: A => B => sig - fwd : A -> B - bwd : B -> A - fwd/bwd : (a : A) -> bwd (fwd a) = a - bwd/fwd : (b : B) -> fwd (bwd b) = b -end -global entry named Operation -type: (opInfo : OpInfo) -> (val : Set) -> (outputs : Set) -> Theory -value: opInfo => val => outputs => sig - opType : opInfo.OpType - opInputs : opInfo.inputArity opType -> val - opOutputs : Iso outputs (opInfo.outputArity opType) -end global entry named PrecedingOutput +in mode: Conjunctive type: (X : Set) -> (rel : X -> X -> Set) -> (x : X) -> (outputs : X -> Set) -> Set value: X => rel => x => outputs => sig y : X isPreceding : rel y x output : outputs y end -global entry named Block -type: (opInfo : OpInfo) -> Theory -value: opInfo => sig - ops : LinearOrder - outputs : ops.car -> Set - payload : (x : ops.car) -> Operation opInfo (PrecedingOutput ops.car ops.follows x outputs) (outputs x) - args : LinearOrder -end -global entry named SSA -type: (opInfo : OpInfo) -> Theory -value: opInfo => sig - RegionId : Set - BlockId : RegionId -> Set - ops : (r : RegionId) -> BlockId r -> Block opInfo -end -- messages + +error[E0316]: cannot use inductively bound variable in a conjunctive context +13 | next/prev : (x : car) -> next (prev x) = x +13 | ^ + +error[E0316]: cannot use inductively bound variable in a conjunctive context +34 | fwd/bwd : (a : A) -> bwd (fwd a) = a +34 | ^ + +error[E0314]: no such variable Iso in scope +41 | opOutputs : Iso outputs (opInfo.outputArity opType) +41 | ^^^ + +error[E0314]: no such variable LinearOrder in scope +51 | ops : LinearOrder +51 | ^^^^^^^^^^^ + +error[E0314]: no such variable Block in scope +65 | ops : (r : RegionId) -> BlockId r -> Block opInfo +65 | ^^^^^ diff --git a/packages/coln-repl/src/Coln/REPL.hs b/packages/coln-repl/src/Coln/REPL.hs index 6e7a6d93..07b42a56 100644 --- a/packages/coln-repl/src/Coln/REPL.hs +++ b/packages/coln-repl/src/Coln/REPL.hs @@ -6,14 +6,14 @@ module Coln.REPL (runRepl) where import Coln.Common import Coln.Core.Globals -import Coln.Core.Params (CtxShape (..), N) +import Coln.Core.Params (CtxShape (..), Mode (..), N) import Coln.Core.Print (DPrettyWithNames (dprettyWithNames), prtIn) import Coln.Core.Realm (Realm) import Coln.Diagnostics import Coln.Elaborator.Environment (emptyElabEnv) import Coln.Elaborator.Judgment (Syn (..)) import Coln.Frontend.Notation -import Coln.Frontend.Parser (decl', syn) +import Coln.Frontend.Parser (decl, syn) import Control.Monad import Control.Monad.State.Strict import Control.Monad.Writer @@ -81,15 +81,15 @@ eval file = do case ntn of -- register declaration Decl name _ _ -> do - put =<< liftIO (decl' diagEnv ge ntn) + put =<< liftIO (decl diagEnv ge ntn) tell [name] -- ignore realms Block "realm" _ _ _ -> pure () -- evaluate expression _ -> liftIO do - let elabEnv = emptyElabEnv (envFor ElaboratorCode) ge - ntnSyn <- (syn @N) diagEnv "" ntn + let elabEnv = emptyElabEnv (envFor ElaboratorCode) ge Conjunctive + ntnSyn <- (syn @N) (contramap ParserCode diagEnv) "" ntn (t, m) <- ntnSyn.elab elabEnv putDoc $ prtIn elabEnv m <+> ":" <+> prtIn elabEnv t <+> "\n" @@ -100,7 +100,7 @@ eval file = do reporter translator = contramap translator $ terminalReporter stdout prettyEntry :: (Name, GlobalEntry) -> DDoc -prettyEntry (x, GlobalEntry t _ a) = +prettyEntry (x, GlobalEntry t _ a _) = vsep [ "global entry named" <+> dpretty x , "type:" <+> prtIn (CtxShape 0 BwdNil) a diff --git a/packages/fnotation/src/FNotation/Kinds.hs b/packages/fnotation/src/FNotation/Kinds.hs index 7be62f2d..d8d5eea4 100644 --- a/packages/fnotation/src/FNotation/Kinds.hs +++ b/packages/fnotation/src/FNotation/Kinds.hs @@ -24,6 +24,7 @@ data Kind | Field | -- | No-space field, like the `x` in `f.x` FieldImmediate + | Mode | Int | String | LParen diff --git a/packages/fnotation/src/FNotation/Lexer.hs b/packages/fnotation/src/FNotation/Lexer.hs index 8408df4d..ae3892d0 100644 --- a/packages/fnotation/src/FNotation/Lexer.hs +++ b/packages/fnotation/src/FNotation/Lexer.hs @@ -320,6 +320,7 @@ run st fresh = '\"' -> string st >> run st False '.' -> advance st >> tryName st (if fresh then Field else FieldImmediate) "period" >> run st False '\'' -> advance st >> tryName st Tag "single quote" >> run st False + '^' -> advance st >> tryName st Mode "at sign" >> run st False '\0' -> emit0 st Eof '`' -> ident st >> run st False c | isDigit c -> (int st >>= emit st Int . VInt) >> run st False diff --git a/packages/fnotation/src/FNotation/Pretty.hs b/packages/fnotation/src/FNotation/Pretty.hs index 04ea4348..4ed8cb7a 100644 --- a/packages/fnotation/src/FNotation/Pretty.hs +++ b/packages/fnotation/src/FNotation/Pretty.hs @@ -92,6 +92,7 @@ prt p = \case Keyword x _ -> dpretty x Field x _ -> "." <> dprettyWithKinds ?lconfig x Tag x _ -> "'" <> dprettyWithKinds ?lconfig x + Mode x _ -> "^" <> dprettyWithKinds ?lconfig x Int i _ -> pretty i String x _ -> "\"" <> pretty x <> "\"" Tuple ns _ -> bracketedTuple $ prtTop <$> ns diff --git a/packages/fnotation/src/FNotation/Reader.hs b/packages/fnotation/src/FNotation/Reader.hs index becdb30b..b213a886 100644 --- a/packages/fnotation/src/FNotation/Reader.hs +++ b/packages/fnotation/src/FNotation/Reader.hs @@ -181,6 +181,7 @@ argStarts = , T.AKeyword , T.Field , T.Tag + , T.Mode , T.Int , T.String , T.Block @@ -236,6 +237,9 @@ argBase st = do T.Tag -> do x <- curName st advanceClose st m $ Tag x + T.Mode -> do + x <- curName st + advanceClose st m $ Mode x T.Int -> do i <- curInt st advanceClose st m $ Int i diff --git a/packages/fnotation/src/FNotation/Trees.hs b/packages/fnotation/src/FNotation/Trees.hs index 54b66c1f..ad9738c4 100644 --- a/packages/fnotation/src/FNotation/Trees.hs +++ b/packages/fnotation/src/FNotation/Trees.hs @@ -37,6 +37,7 @@ data NtnGeneric a | Keyword Name a | Field Name a | Tag Name a + | Mode Name a | Int Int a | String Text a | Error a @@ -68,6 +69,7 @@ startPos (Ident _ s) = s.start startPos (Keyword _ s) = s.start startPos (Field _ s) = s.start startPos (Tag _ s) = s.start +startPos (Mode _ s) = s.start startPos (Int _ s) = s.start startPos (String _ s) = s.start startPos (Tuple _ s) = s.start @@ -82,6 +84,7 @@ endPos (Ident _ s) = s.end endPos (Keyword _ s) = s.end endPos (Field _ s) = s.end endPos (Tag _ s) = s.end +endPos (Mode _ s) = s.end endPos (Int _ s) = s.end endPos (String _ s) = s.end endPos (Tuple _ s) = s.end @@ -102,6 +105,7 @@ head (Ident x _) = "Ident" <+> dpretty x head (Keyword x _) = "Keyword" <+> dpretty x head (Field x _) = "Field" <+> dpretty x head (Tag x _) = "Tag" <+> dpretty x +head (Mode x _) = "Mode" <+> dpretty x head (Int i _) = "Int" <+> pretty i head (String s _) = "String" <+> pretty s head (Tuple _ _) = "Tuple" @@ -116,6 +120,7 @@ children (Ident _ _) = [] children (Keyword _ _) = [] children (Field _ _) = [] children (Tag _ _) = [] +children (Mode _ _) = [] children (Int _ _) = [] children (String _ _) = [] children (Tuple ns _) = ns