{"id":47300553,"url":"https://github.com/alexkeizer/QPFTypes","last_synced_at":"2026-03-31T06:00:42.169Z","repository":{"id":38829711,"uuid":"470204772","full_name":"alexkeizer/QPFTypes","owner":"alexkeizer","description":"A WIP definitional (co)datatype package for Lean4","archived":false,"fork":false,"pushed_at":"2026-02-21T20:50:54.000Z","size":588,"stargazers_count":47,"open_issues_count":20,"forks_count":5,"subscribers_count":5,"default_branch":"main","last_synced_at":"2026-02-22T01:24:47.824Z","etag":null,"topics":["codatatypes","coinduction","coinductive-types","datatypes","lean","lean4"],"latest_commit_sha":null,"homepage":"","language":"Lean","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/alexkeizer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-03-15T14:48:15.000Z","updated_at":"2026-02-21T20:50:31.000Z","dependencies_parsed_at":"2023-08-27T23:41:35.951Z","dependency_job_id":"883d6ddf-f8ee-4a90-ba0d-ef4bf6344a0b","html_url":"https://github.com/alexkeizer/QPFTypes","commit_stats":null,"previous_names":["alexkeizer/qpftypes"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/alexkeizer/QPFTypes","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexkeizer%2FQPFTypes","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexkeizer%2FQPFTypes/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexkeizer%2FQPFTypes/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexkeizer%2FQPFTypes/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexkeizer","download_url":"https://codeload.github.com/alexkeizer/QPFTypes/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexkeizer%2FQPFTypes/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31223287,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-31T04:08:55.938Z","status":"ssl_error","status_checked_at":"2026-03-31T04:08:47.883Z","response_time":111,"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":["codatatypes","coinduction","coinductive-types","datatypes","lean","lean4"],"created_at":"2026-03-17T01:38:19.981Z","updated_at":"2026-03-31T06:00:42.159Z","avatar_url":"https://github.com/alexkeizer.png","language":"Lean","funding_links":[],"categories":["Lean"],"sub_categories":[],"readme":"\n# A (co)datatype package for Lean 4, based on Quotients of Polynomial Functors\n\nThis library implements a `codata` command, which can be used to define *coinductive* types in [Lean 4](https://leanprover-community.github.io/)\nusing a syntax similar to `inductive`. For example, the following specifies a type of (potentially)\ninfinite lists.\n\n```lean4\n/-- Infinite lists -/\ncodata Stream α \n  | cons : α → CoList α → CoList α\n```\n```lean4\n/-- Potentially infinite Lists -/\ncodata CoList α\n  | nil : CoList α\n  | cons : α → CoList α → CoList α\n```\n\nThe framework is *compositional*, so we can use `CoList` in subsequent specifications.\n\n```lean4\n/-- Potentially infinite trees -/\ncodata CoTree α \n  | node : α → CoList (CoTree α) → CoTree α \n```\n\nWe can even mix induction and coinduction. However, the framework used by `codata` does not play\nnice with `inductive`. So, the library also provides a `data` command for inductive types, using\nthat same framework.\n\n```lean4\n/-- Infinitely branching, finite depth trees\n    That is, one node may have infinitely many children, \n    but the depth of the tree is limited.\n-/\ndata CoTree α \n  | node : α → CoList (CoTree α) → CoTree α \n```\n\n\n# Live and Dead variables\n\nBinders without any type ascription, such as in the examples so far, are called *live* parameters and assumed to live in `Type _`, where the universe level is inferred.\nNote that this universe level is the same for all live parameters.\n\nConversely, binders that do specify a type, even if that type is `Type _` are *dead* parameters.\n\nThis distinction becomes important for subsequent definition: it is only allowed to nest (co)induction behind live parameters. It is thus best to leave out type ascription where possible. That said, live variables have a few more restrictions in where they may appear.\n\n```lean4\ncodata CoList' (α : Type _) -- In this definition, `α` is a dead parameter\n  | nil : CoList' α \n  | cons : α → CoList' α → CoList' α\n\n/-- The following is not accepted: \n    It not allowed to nest a corecursive occurrence of the type to be defined \n    behind `CoList'`, when its parameter is defined as dead.\n-/\ncodata CoTree (α : Type _)\n  | node : α → CoList' (CoTree α) → CoTree α \n  --           ^^^^^^^^^^^^^^^^^^ \u003c-- this is where it goes wrong\n```\n\nReusing the type ascription to distinguish live/dead variable is not ideal; in future we'll either introduce dedicated syntax, or automatically determine which variables can be live and which have to be dead.\n\n\n\n# Limitations\n\nThe implementation is intended as a proof-of-concept. It is still very rough, and not at all ready for serious use.\n\nFundamentally, (co)recursive families of types or even mutually (co)inductive types are not supported yet, and the only way to define (total) (co)recursive functions is through the low-level `MvQPF.Fix.drec` and `MvQPF.Cofix.corec` (co)recursion principles.\n\nBeyond this, the implementation is far from perfect and might throw errors for specifications that should be supported. Feel free to open issues for any such specifications.\n\n\n# Try it Out\n\nYou can clone https://github.com/alexkeizer/qpf4-example for an example project that imports this package. There is also https://gitpod.io/#https://github.com/alexkeizer/qpf4-example, allowing you to play with codatatypes directly in your browser, no setup needed.\n\n\n\n# Organization\n\nTODO\n\n\n\n\n\n# References\n\nFor a thorough discussion about the foundations and implementation of this library, see the accompanying MSc. Thesis by Alex C. Keizer: [Implementing a definitional (co)datatype package in Lean 4, based\non quotients of polynomial functors](https://eprints.illc.uva.nl/id/eprint/2239/1/MoL-2023-03.text.pdf)\n\n\nThe foundations of this library come from [avigad/qpf](https://github.com/avigad/qpf).\nThere it was described as\n\u003e  This repository contains a formalization of data type constructions in Lean, by Jeremy Avigad, Mario Carneiro, and Simon Hudon. A       preliminary version of the work is described in this talk: [http://www.andrew.cmu.edu/user/avigad/Talks/qpf.pdf](http://www.andrew.cmu.edu/user/avigad/Talks/qpf.pdf).\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexkeizer%2FQPFTypes","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexkeizer%2FQPFTypes","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexkeizer%2FQPFTypes/lists"}