{"id":20658556,"url":"https://github.com/gergoerdi/universe-of-syntax","last_synced_at":"2026-03-10T06:32:37.704Z","repository":{"id":66978077,"uuid":"110766035","full_name":"gergoerdi/universe-of-syntax","owner":"gergoerdi","description":"A universe of scope- and type-safe syntaxes (syntices?). Includes generic implementation of type-preserving renaming/substitution with all the proofs you could possibly need.","archived":false,"fork":false,"pushed_at":"2017-12-10T15:35:36.000Z","size":39,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-03-09T23:51:57.696Z","etag":null,"topics":["agda","lambda-calculus","normalization","simply-typed-lambda-calculus","substitution"],"latest_commit_sha":null,"homepage":"","language":"Agda","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gergoerdi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-11-15T01:16:52.000Z","updated_at":"2021-09-10T06:03:09.000Z","dependencies_parsed_at":"2023-02-23T15:45:56.305Z","dependency_job_id":null,"html_url":"https://github.com/gergoerdi/universe-of-syntax","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/gergoerdi/universe-of-syntax","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gergoerdi%2Funiverse-of-syntax","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gergoerdi%2Funiverse-of-syntax/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gergoerdi%2Funiverse-of-syntax/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gergoerdi%2Funiverse-of-syntax/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gergoerdi","download_url":"https://codeload.github.com/gergoerdi/universe-of-syntax/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gergoerdi%2Funiverse-of-syntax/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30326891,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-10T05:25:20.737Z","status":"ssl_error","status_checked_at":"2026-03-10T05:25:17.430Z","response_time":106,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agda","lambda-calculus","normalization","simply-typed-lambda-calculus","substitution"],"created_at":"2024-11-16T18:26:56.479Z","updated_at":"2026-03-10T06:32:37.670Z","avatar_url":"https://github.com/gergoerdi.png","language":"Agda","funding_links":[],"categories":[],"sub_categories":[],"readme":"Universe of scope- and type-safe syntaxes\n=========================================\n\nThis repository contains Agda code in an experiment to come up with a\ngeneric representation of languages. The aim is a library that given a\ndescription of a language, will deliver the following functionality to\nthe user:\n\n* An intrinsically typed representation of well-typed, well-scoped\n  terms `Tm : Ctx → Ty → Set`\n\n* A representation of well-scoped (but not necessarily well-typed)\n  expressions `Expr : ℕ → Set`\n\n* A representation of syntactically valid, but not necessarily\n  well-scoped formulas `Form : Set`\n\n* \"All\" the proofs about type-preserving simultaneous substitution\n  over the typed representation\n\n* A type erasure function `untype : Tm Γ t → Expr (size Γ)`\n\n* A scope checker `resolveNames : Scope n → Form → Maybe (Expr n)`\n\nAs a validating example, I've added a purely symbolic implementation\nof STLC: reduction rules are explicit and defined in terms of\nsubstitution, and normalization is proven a la the relevant chapter of\nPierce's Software Foundations.\n\nSyntax definitions\n------------------\n\nA given language is described using the Agda datatype `Code`:\n\n```\ndata Binder : Set where\n  bound unbound : Binder\n\nShape : ℕ → Set\nShape n = List (Vec Binder n)\n\ndata Code : Set₁ where\n  sg : (A : Set) → (A → Code) → Code\n  node : (n : ℕ) (shape : Shape n) (wt : Vec Ty n → All (const Ty) shape → Ty → Set) → Code\n```\n\nThe only difference to https://gallais.github.io/pdf/draft_fscd17.pdf\nis that the `node` constructor has a unified global view of all the\nsubterms; in particular, of all the types of the subterms. The meaning\nof the well-typedness constraint `wt` is that it takes two collections\nof types: the types of the `n` newly bound variables, the types of the\nsubterms; it also receives the type of the term just being\nconstructed.\n\nThe idea behind `wt` is to encode the typing constraints the same way\nas one encodes a GADT in Haskell using only existentials and type\nequalities. Here, we use existentials for the types of subterms, and\nallow arbitrary constraints between them. The typed representation for\na given code carries witnesses of well-typedness in their constructor\nfor `node` (omitting some details here):\n\n```\ndata Con (Γ : Ctx) (t : Ty) : Code → Set where\n  sg : ∀ {A c} x → Con Γ t (c x) → Con Γ t (sg A c)\n  node : ∀ {n shape wt} (ts₀ : Vec Ty n) {ts : All (const Ty) shape} (es : Children Γ ts₀ ts) →\n    {{_ : wt ts₀ ts t}} → Con Γ t (node n shape wt)\n\ndata Tm (Γ : Ctx) : Ty → Set where\n  var : ∀ {t} → Var t Γ → Tm Γ t\n  con : ∀ {t} → Con Γ t code → Tm Γ t\n```\n\nType systems\n------------\n\nI have no idea yet what kind of type systems one can describe this\nway; I've named the library `SimplyTyped` as a conservative lower\nbound:)\n\nSTLC\n----\n\nThe following example encodes STLC:\n\n```\ndata `STLC : Set where\n  `lam `app : `STLC\n\nSTLC : Code\nSTLC = sg `STLC λ\n  { `lam   → sg Ty λ t → node 1 ((bound ∷ []) ∷ []) λ { (t′ ∷ []) (u ∷ []) t₀ → t′ ≡ t × t₀ ≡ t ▷ u }\n  ; `app   → node 0 ([] ∷ [] ∷ []) λ { [] (t₁ ∷ t₂ ∷ []) t → t₁ ≡ t₂ ▷ t }\n  }\n```\n\nFor ````lam```bda abstractions, we store an argument type, and then\nbind one new variable, visible in one subterm; the well-typedness\nconstraint then requires the type of the newly bound variable to match\nthe user-supplied one, while also requiring the result type to be the\ncorrect function type.\n\nFor function `app`lication, no new variables are bound, so the\nwell-typedness constraint only concerns the types of subterms.\n\nThe following pattern synonyms illustrate the typed representation of\n`STLC` (unfortunately, Agda doesn't support type signatures on pattern\nsynonyms, hence the comments):\n\n```\n-- [lam] : ∀ {Γ u} t → Tm (Γ , t) u → Tm Γ (t ▷ u)\npattern [lam] t e = con (sg `lam (sg t (node (_ ∷ []) (e ∷ []) {{refl , refl}})))\n\n-- _[·]_ : ∀ {Γ u t} → Tm Γ (u ▷ t) → Tm Γ u → Tm Γ t\npattern _[·]_ f e = con (sg `app (node [] (f ∷ e ∷ []) {{refl}}))\n```\n\nIf we want to add `let` to our language, that's expressible with the\nfollowing change to `STLC`:\n\n```\ndata `STLC : Set where\n  `lam `app `let : `STLC\n\nSTLC : Code\nSTLC = sg `STLC λ\n  { `lam   → sg Ty λ t → node 1 ((bound ∷ []) ∷ [])\n               λ { (t′ ∷ []) (u ∷ []) t₀ → t′ ≡ t × t₀ ≡ t ▷ u }\n  ; `app   → node 0 ([] ∷ [] ∷ [])\n               λ { [] (t₁ ∷ t₂ ∷ []) t → t₁ ≡ t₂ ▷ t }\n  ; `let   →  node 1 ((unbound ∷ []) ∷ (bound ∷ []) ∷ [])\n               λ { (t₀ ∷ []) (t₀′ ∷ t₁ ∷ []) t → t₀′ ≡ t₀ × t ≡ t₁ }\n  }\n```\n\nIn fact, we can easily implement a transformation that gets rid of\n`let`s in some input language by inlining them:\n\n```\ndata Phase : Set where\n  input inlined : Phase\n\ndata `STLC : Phase → Set where\n  `lam `app : ∀ {p} → `STLC p\n  `let : `STLC input\n\nSTLC : Phase → Code\nSTLC p = sg (`STLC p) aux\n  where\n    aux : `STLC p → Code\n    aux `lam   = sg Ty λ t → node 1 ((bound ∷ []) ∷ []) λ { (t′ ∷ []) (u ∷ []) t₀ → t′ ≡ t × t₀ ≡ t ▷ u }\n    aux `app   = node 0 ([] ∷ [] ∷ []) λ { [] (t₁ ∷ t₂ ∷ []) t → t₁ ≡ t₂ ▷ t }\n    aux `let   = node 1 ((unbound ∷ []) ∷ (bound ∷ []) ∷ []) λ { (t₀ ∷ []) (t₁ ∷ t₂ ∷ []) t → t₀ ≡ t₁ × t₂ ≡ t }\n\nopen import SimplyTyped.Ctx Ty\nopen import SimplyTyped.Typed hiding (Tm)\n\nTm : (p : Phase) → Ctx → Ty → Set\nTm p = SimplyTyped.Typed.Tm (STLC p)\n\npattern [lam] t e = con (sg `lam (sg t (node (_ ∷ []) (e ∷ []) {{refl , refl}})))\npattern _[·]_ f e = con (sg `app (node [] (f ∷ e ∷ []) {{refl}}))\npattern [let]_[in]_ e₀ e = con (sg `let (node (_ ∷ []) (e₀ ∷ e ∷ []) {{refl , refl}}))\n\nopen import SimplyTyped.Sub (STLC inlined)\n\ninline : ∀ {Γ Δ t} → Γ ⊢⋆ Δ → Tm input Δ t → Tm inlined Γ t\ninline σ (var v)           = subᵛ σ v\ninline σ ([lam] t e)       = [lam] t (inline (shift σ) e)\ninline σ (f [·] e)         = inline σ f [·] inline σ e\ninline σ ([let] e₀ [in] e) = inline (σ , inline σ e₀) e\n```\n\nWe can also express `letrec` by simply making the newly-introduced variable\nbound in both subterms:\n\n```\n  ; `letrec →  node 1 ((bound ∷ []) ∷ (bound ∷ []) ∷ [])\n               λ { (t₀ ∷ []) (t₀′ ∷ t₁ ∷ []) t → t₀′ ≡ t₀ × t ≡ t₁ }\n```\n\nOf course, while adding the semantics of `letrec` is straightforward,\nmodifying the proof of strong normalization to cover this extended\nlanguage would be... tricky :)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgergoerdi%2Funiverse-of-syntax","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgergoerdi%2Funiverse-of-syntax","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgergoerdi%2Funiverse-of-syntax/lists"}