{"id":16313969,"url":"https://github.com/lysxia/coq-ceres","last_synced_at":"2025-03-22T20:35:41.422Z","repository":{"id":36134355,"uuid":"193287020","full_name":"Lysxia/coq-ceres","owner":"Lysxia","description":"Coq library for serialization to S-expressions","archived":false,"fork":false,"pushed_at":"2023-07-03T10:10:26.000Z","size":272,"stargazers_count":17,"open_issues_count":4,"forks_count":1,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-05-01T16:50:05.862Z","etag":null,"topics":["coq","debug","pretty-print","serialization"],"latest_commit_sha":null,"homepage":null,"language":"Coq","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Lysxia.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-06-22T23:12:40.000Z","updated_at":"2023-10-10T16:26:42.000Z","dependencies_parsed_at":"2024-01-13T17:02:14.257Z","dependency_job_id":"2695d4c8-8c74-4ccc-aad1-9448cc043dc5","html_url":"https://github.com/Lysxia/coq-ceres","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lysxia%2Fcoq-ceres","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lysxia%2Fcoq-ceres/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lysxia%2Fcoq-ceres/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Lysxia%2Fcoq-ceres/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Lysxia","download_url":"https://codeload.github.com/Lysxia/coq-ceres/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245020172,"owners_count":20548155,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["coq","debug","pretty-print","serialization"],"created_at":"2024-10-10T21:52:48.880Z","updated_at":"2025-03-22T20:35:41.056Z","avatar_url":"https://github.com/Lysxia.png","language":"Coq","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cérès [![CircleCI](https://circleci.com/gh/Lysxia/coq-ceres.svg?style=shield)](https://circleci.com/gh/Lysxia/coq-ceres)\n\nCérès is a Coq library for serialization to S-expressions.\n\nS-expressions\n-------------\n\nS-expressions are uniform representations of structured data.\n\nThey are an alternative to plain strings as used by `Show` in Haskell and\n`Debug` in Rust for example.\nS-expressions are more amenable to programmatic consumption, avoiding custom\nparsers and enabling flexible formatting strategies.\n\n### Example\n\nThis S-expression...\n\n```\n(example\n  (message \"I'm a teapot\")\n  (code 418))\n```\n\n... corresponds to this `sexp` in Coq.\n\n```coq\nDefinition example : sexp :=\n  [ Atom \"example\"\n  ; [ Atom \"message\" ; Atom (Str \"I'm a teapot\") ]\n  ; [ Atom \"code\" ; Atom 418%Z ]\n  ].\n```\n\n### Documentation\n\nThe [tutorial module](https://lysxia.github.io/coq-ceres/Tutorial.html) is a good place for a quick start.\n\n[Link to the rendered documentation.](https://lysxia.github.io/coq-ceres/toc.html)\n\nSimplified overview\n-------------------\n\nThis library offers a type `sexp` with two constructors:\n\n```coq\nInductive sexp :=\n| Atom (a : atom)\n| List (xs : list sexp)\n.\n```\n\nAtoms are identifiers (`Raw`), numbers (`Num`) or strings (`Str`).\n\n```coq\nVariant atom : Set :=\n| Num (n : Z)       (* Integers. *)\n| Str (s : string)  (* Literal strings. *)\n| Raw (s : string)  (* Simple atoms (e.g., ADT tags). *)\n                    (* Should fit in this alphabet: [A-Za-z0-9'=+*/:!?@#$%^\u0026\u003c\u003e.,|_~-]. *)\n.\n```\n\nTwo classes `Serialize` and `Deserialize` are provided to define canonical\nserializers and deserializers between your types and S-expressions.\nThe following functions are provided for conversions to `sexp` or directly to\n`string`:\n\n```coq\nDefinition to_sexp {A} `{Serialize A} : A -\u003e sexp.\nDefinition from_sexp {A} `{Deserialize A} : sexp -\u003e error + A.\n\nDefinition to_string {A} `{Serialize A} : A -\u003e string.\nDefinition from_string {A} `{Deserialize A} : string -\u003e error + A.\n```\n\nUsage\n-----\n\nImport the main module of the library.\n\n```coq\nRequire Import Ceres.Ceres.\n```\n\nThis exports:\n\n- `CeresS`: the core definitions for S-expressions.\n- `CeresSerialize`: the `Serialize` type class (`sexp -\u003e error + mytype`).\n- `CeresDeserialize`: the `Deserialize` type class (`mytype -\u003e sexp`).\n- `CeresRoundtrip`: roundtrip properties for serializers and deserializers.\n- `CeresFormat`: format S-expressions as strings (`sexp -\u003e string`).\n- `CeresParser`: S-expression parser (`string -\u003e error + sexp`).\n\nOther modules in the library:\n\n- `CeresParserUtils`: low-level primitives for the S-expression parser\n- `CeresParserRoundtrip`, `CeresParserRoundtripProof`:\n  Correctness proof of the parser. Currently, only soundness is proved\n  (i.e., parse-then-print roundtrip).\n\nInternals:\n\n- `CeresUtils`: miscellaneous.\n- `CeresParserInternal`: S-expression parser, internals\n- `CeresString`: general string utilities.\n\nCore definitions\n----------------\n\nThe type of S-expressions is actually parameterized by the type of atoms.\n\n```coq\nInductive sexp_ (A : Type) :=\n| Atom_ (a : A)\n| List (xs : list (sexp_ A))\n.\n```\n\nBy default, it is specialized to the `atom` type, so that the main S-expression type is\n`sexp := sexp_ atom`.\n\n```coq\nNotation sexp := (sexp_ atom).\nNotation Atom := (@Atom_ atom).\n\nCoercion Num : Z \u003e-\u003e atom.\nCoercion Raw : string \u003e-\u003e atom.\n\n(* Destructors *)\nDefinition get_Num : atom -\u003e option Z.\nDefinition get_Str : atom -\u003e option string.\nDefinition get_Raw : atom -\u003e option string.\n```\n\nSerialization\n-------------\n\nSerializers can be defined as instances of the `Serialize` type class.\n\n```coq\nClass Serialize (A : Type) : Type :=\n  to_sexp : A -\u003e sexp.\n```\n\nS-expressions can be serialized to a `string`. Thus, so can serializable types.\n\n```coq\nDefinition to_string {A : Type} `{Serialize A} : A -\u003e string.\n```\n\nFor numeric types, it is sufficient to define a conversion to `Z` as an\ninstance of `Integral`.\n\n```coq\nClass Integral (A : Type) : Type :=\n  to_Z : A -\u003e Z.\n\nInstance Serialize_Integral (A : Type) : Integral A -\u003e Serialize A.\n```\n\nDeserialization\n---------------\n\nGoing the other way requires some additional error handling.\n\n```coq\nClass Deserialize (A : Type) : Type := ...\n\nDefinition from_sexp {A} `{Deserialize A} : sexp -\u003e error + A.\nDefinition from_string {A} `{Deserialize A} : string -\u003e error + A.\n```\n\nAgain, a simplified interface for numeric types is thus provided,\nwith a `SemiIntegral` class.\n\n```coq\nClass SemiIntegral (A : Type) : Type :=\n  from_Z : Z -\u003e option A.\n\nInstance Deserialize_SemiIntegral (A : Type) : SemiIntegral A -\u003e Deserialize A.\n```\n\nRoundtrip properties\n--------------------\n\nThe module `CeresRoundtrip` defines some roundtripping properties\nand lemmas to help prove them.\n\n```coq\nClass CompleteClass {A} `{Serialize A} `{Deserialize A} : Prop.\nClass SoundClass {A} `{Serialize A} `{Deserialize A} : Prop.\n```\n\nGeneric encoding\n----------------\n\nThere are no strong requirements on the encodings implemented by `Serialize`\nand `Deserialize` instances, but some utilities are provided for the following\ndefault encoding for inductive types:\n\n- Nullary constructors are atoms `con`.\n- Non-nullary constructors are lists `(con x y z)`.\n\nSerialization is straightforward by pattern-matching.\n\nFor deserialization, the module `CeresDeserialize.Deser` provides\nsome utilities.\n\n### Standard types\n\n- `unit`, `bool`, `sum` and `option` follow that standard encoding.\n- `(x, y) : prod A B` is encoded as `(X Y)` where `X` and `Y` are the encodings of `x` and `y`.\n- `[x; y; z] : list A` is encoded as `(X Y Z)`.\n- `\"somestring\" : string` is encoded as `\"somestring\"`.\n- `\"c\" : ascii` is encoded as `\"c\"`.\n- `33 : Z` (or `N`, `nat`) is encoded as `33`.\n\n### Recursive types\n\nRecursive serializers and deserializers can be defined using explicit fixpoints.\n\nFor deserializers, that means to bind the expression explicitly, since that's\nthe decreasing argument, but immediately pass it as the last argument of\n`Deser.match_con`:\n\n```coq\nDefinition Deserialize_unary : Deserialize nat :=\n  fix deser_nat (l : loc) (e : sexp) {struct e} :=\n    Deser.match_con \"nat\"\n      [ (\"Z\", 0%nat) ]\n      [ (\"S\", Deser.con1 S deser_nat) ] l e.\n```\n\nDeveloper notes\n---------------\n\n### Build the documentation\n\nExtra directories:\n\n- `coqdocjs`: a clone of [coqdocjs](https://github.com/coq-community/coqdocjs)\n- `doc`: a clone of this repo's `gh-pages` branch\n\n```\nmake html \u0026\u0026 rm -r doc/docs \u0026\u0026 mv html doc/docs\ncd doc\ngit add docs \u0026\u0026 git commit -m \"Update\" \u0026\u0026 git push\n```\n\nSee also\n--------\n\n- Real World OCaml, [Chapter 17, Data Serialization with\n  S-expressions](https://v1.realworldocaml.org/v1/en/html/data-serialization-with-s-expressions.html).\n- [Down with Show!](https://harry.garrood.me/blog/down-with-show-part-3/), a\n  blog post by Harry Garrood advocating for using structured representations\n  instead of strings.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flysxia%2Fcoq-ceres","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flysxia%2Fcoq-ceres","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flysxia%2Fcoq-ceres/lists"}