{"id":22553755,"url":"https://github.com/tribbloid/shapesafe","last_synced_at":"2025-04-10T04:23:24.541Z","repository":{"id":45914939,"uuid":"230655395","full_name":"tribbloid/shapesafe","owner":"tribbloid","description":"SHAPE/S∀F∃: static prover/type-checker for N-D array programming in Scala, a use case of intuitionistic type theory","archived":false,"fork":false,"pushed_at":"2024-03-24T21:16:04.000Z","size":8194,"stargazers_count":32,"open_issues_count":1,"forks_count":4,"subscribers_count":8,"default_branch":"master","last_synced_at":"2025-03-24T05:43:33.264Z","etag":null,"topics":["linear-algebra","machine-learning","program-verification","scala","shape-safety","type-theory"],"latest_commit_sha":null,"homepage":"","language":"Scala","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/tribbloid.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":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2019-12-28T19:28:50.000Z","updated_at":"2025-03-01T23:55:10.000Z","dependencies_parsed_at":"2023-12-14T23:08:15.277Z","dependency_job_id":"294b5759-1d67-4ab7-b3e6-bca62d165a66","html_url":"https://github.com/tribbloid/shapesafe","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tribbloid%2Fshapesafe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tribbloid%2Fshapesafe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tribbloid%2Fshapesafe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tribbloid%2Fshapesafe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tribbloid","download_url":"https://codeload.github.com/tribbloid/shapesafe/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248155687,"owners_count":21056689,"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":["linear-algebra","machine-learning","program-verification","scala","shape-safety","type-theory"],"created_at":"2024-12-07T18:11:06.331Z","updated_at":"2025-04-10T04:23:24.526Z","avatar_url":"https://github.com/tribbloid.png","language":"Scala","funding_links":[],"categories":[],"sub_categories":[],"readme":"![SHAPE/S∀F∃](doc/.asset/logo/binary.png)\n\n**shapesafe** is the one-size-fits-all compile-time verifier for numerical linear algebra on JVM, obvious shape and indexing errors in tensor operations are captured by scala's typing system.\n\nShapesafe allows programs to actively prove themselves while being written. The following capabilities are enabled in release v0.1.0:\n\n##### static \u0026 runtime-dependent tensor shapes of arbitrary rank\n\n![S1](doc/video/S1.gif)\n\n##### named tensor: each dimension is indexed by both its name and ordinal number\n\n![S2](doc/video/S2.gif)\n\n##### tensor contractions \u0026 operations that depends on index equality, (all cases of EinSum, dot/cross/matrix/hadamard product)\n\n![S3](doc/video/S3.gif)\n\n##### operations that depends on shape arithmetics (convolution, direct sum, kronecker product, flatten/reshape)\n\n![S4](doc/video/S4.gif)\n\n##### complex function composition, with no implicit scope\n\n![S5](doc/video/S5.gif)\n\nThese screenshots can be reproduced by compiling our showcases in Visual Studio Code + Scala (Metals) plugin:\n\n- [Part 1](https://github.com/tribbloid/shapesafe-demo/blob/main/src/main/scala/shapesafe/demo/core/ShowCase.scala)\n  - [Part 1 - error captured](https://github.com/tribbloid/shapesafe-demo/blob/main/src/main/scala-shouldFail/shapesafe/demo/core/ShowCase_Refute.scala)\n- [Part 2](https://github.com/tribbloid/shapesafe-demo/blob/main/src/main/scala-complex/shapesafe/demo/core/ShowCase_Complex.scala)\n  - [Part 2 - error captured](https://github.com/tribbloid/shapesafe-demo/blob/main/src/main/scala-shouldFail/shapesafe/demo/core/ShowCase_RefuteComplex.scala)\n\n**It is not a tensor computing library!** Instead, it is designed to be embedded into existing libraries to enable less error-prone prototyping (see Roadmap for possible augmentations).\n\nshapesafe started as an experiment to understand intuitionistic type theory used in compiler design, it minimally depends on [singleton-ops](https://github.com/fthomas/singleton-ops) and [shapeless](https://github.com/milessabin/shapeless).\n\nSupport for scala-2.13 is always guaranteed, supports for scala-2.12 or scala-js should only be enforced intermittently and upon request, please create (or vote for) tickets to backport for a specific compiler.\n\n### Build Status\n\n| branch \\ profile | Scala-2.13                                                                                 | Scala-2.13 w/ splain plugin                                                                       |\n|------------------|--------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------|\n| master           | ![CI](https://github.com/tribbloid/shapesafe/workflows/CI/badge.svg?branch=master)         | ![CI](https://github.com/tribbloid/shapesafe/workflows/CI-splain/badge.svg?branch=master)         |\n| 0.1.4            | ![CI](https://github.com/tribbloid/shapesafe/workflows/CI/badge.svg?branch=Release/v0.1.4) | ![CI](https://github.com/tribbloid/shapesafe/workflows/CI-splain/badge.svg?branch=Release/v0.1.4) |\n| 0.1.3            | ![CI](https://github.com/tribbloid/shapesafe/workflows/CI/badge.svg?branch=Release/v0.1.3) | ![CI](https://github.com/tribbloid/shapesafe/workflows/CI-splain/badge.svg?branch=Release/v0.1.3) |\n| 0.1.2            | ![CI](https://github.com/tribbloid/shapesafe/workflows/CI/badge.svg?branch=Release/v0.1.2) | ![CI](https://github.com/tribbloid/shapesafe/workflows/CI-splain/badge.svg?branch=Release/v0.1.2) |\n| 0.1.1            | ![CI](https://github.com/tribbloid/shapesafe/workflows/CI/badge.svg?branch=Release/v0.1.1) | ![CI](https://github.com/tribbloid/shapesafe/workflows/CI-splain/badge.svg?branch=Release/v0.1.1) |\n| 0.1.0            | ![CI](https://github.com/tribbloid/shapesafe/workflows/CI/badge.svg?branch=Release/v0.1.0) | ![CI](https://github.com/tribbloid/shapesafe/workflows/CI-splain/badge.svg?branch=Release/v0.1.0) |\n| dev (latest WIP) | ![CI](https://github.com/tribbloid/shapesafe/workflows/CI/badge.svg?tag=latest)            | ![CI-legacy](https://github.com/tribbloid/shapesafe/workflows/CI-splain/badge.svg?tag=latest)     |\n\n### Tutorial\n\n- Setup `shapesafe-core` in your scala project [using your favourite dependency manager](https://search.maven.org/artifact/ai.acyclic.shapesafe/shapesafe-core_2.13/0.1.0/jar). Replace the version number with that of the latest compatible release \n\n- Compile our [Casually Written Tutorial](https://github.com/tribbloid/shapesafe-demo/tree/main/src/main/scala-shouldFail/shapesafe/demo/tutorial) and learn the basics by reading code and errors.\n  \n  - The [shapesafe-demo](https://github.com/tribbloid/shapesafe-demo) project provides a reference setup using sbt\n  - Our Scastie snippet (courtesy of EPFL Scala Center) uses the same setup but can run in browser\n    - [Part 1 - Static Reasoning, Arity Operations](https://scastie.scala-lang.org/tribbloid/ZUhG9iypQB2fYeScr6odMA)\n    - [Part 2 - Shape Operations](https://scastie.scala-lang.org/tribbloid/4r2YHkQBQv6mwfn5awAq9A)\n    - [Part 3 - Tensor Typing](https://scastie.scala-lang.org/tribbloid/fkZ1Er6UTq6axi87MbXVKw)\n    - (if the environment timeout please comment out part of the source code and try again)\n\n### Roadmap\n\n##### High priority\n\n- Symbolic reasoning for variable dimensions, using Ring/Field axioms and natural deduction\n- Type-checking for [EinOps](https://openreview.net/forum?id=oapKSVM2bcj)\n- DJL integration\n\n##### Low priority\n\n- DL4j \u0026 ND4j integration\n- breeze integration (only tensors to up to rank-2 is required)\n\n### How to compile\n\nIn POSIX shell, run `./dev/make-all.sh`\n\nGuaranteed to be working by [Continuous Integration](.github/workflows/main.yml)\n\nYou must have installed a JDK that supports Gradle 7+ before the compilation\n\n### Architecture (Recommended for user who finished our tutorial)\n\n##### Lazy Verification\n\nIt can be observed immediately in the tutorial that calling functions in shapesafe\nrequires no implicit summoning of type class. In fact, their return types are represented as computation graphs rather than computed Arities or Shapes.\nAs a trade-off, errors in these computation graphs can't be detected as-is:\n\n```scala\nval a = Shape(1, 2)\nval b = Shape(3, 4)\nval s1 = (a \u003e\u003c b).:\u003c\u003c=*(\"i\", \"j\")\ns1.peek\n\n// [INFO] 1 \u003e\u003c 2 \u003e\u003c (3 \u003e\u003c 4) :\u003c\u003c= (i \u003e\u003c j)\n```\n\nThis is a deliberate design which allows complex operand compositions to be defined with no boilerplate (see [example above](#complex-function-composition-with-no-implicit-scope) and [TutorialPart1/StaticReasoning](https://github.com/tribbloid/shapesafe-demo/blob/d5fdd40c896e649338d2b9b6a627e6e4ab985e59/src/main/scala-shouldFail/shapesafe/demo/tutorial/TutorialPart1.scala#L59)).\n\nDetection of errors only happens once the expression is evaluated (by explicitly calling `.eval` or `.reason`), which summons all algebraic rules like a proof assistant:\n\n```scala\ns1.eval\n\n// [ERROR] Dimension mismatch\n//   ...\n```\n\nIn the above example, calling `eval` instructs the compiler to summon a series of type classes as lemmata to prove / refute the correctness of the expression:\n\n| lemma                                         |     | expression                              |\n| ---------------------------------------------:|:---:| --------------------------------------- |\n|                                               |     | (1 \u003e\u003c 2) **\u003e\u003c** (3 \u003e\u003c 4) \\:\u003c\u003c= (i \u003e\u003c j) |\n| (prove outer product)                         | =   | 1 \u003e\u003c 2 \u003e\u003c 3 \u003e\u003c 4 **\\:\u003c\u003c=** (i \u003e\u003c j)     |\n| (refute naming of tensor: Dimension mismatch) | !   |                                         |\n\nEvidently, `eval` can only be used *iff.* each shape operand in the expression (in the above example `a` and `b`)  is\neither already evaluated, or can be evaluated in the same scope. This is the only case when implicit arguments has to be\ndeclared by the user.\n\nAt this moment, all algebraic rules are defined to manipulate the following 2 types of expressions:\n\n- **Arity** - describing 1D vectors:\n\n![Arity](doc/ArityTypeHierarchy.png)\n\n- **Shape** - describing ND tensors:\n\n![Shape](doc/ShapeTypeHierarchy.png)\n\nShapesafe works most efficiently if dimensions of all tensors are either constants (represented\nby `shapesafe.core.arity.Const`), or unchecked (represented by `shapesafe.core.arity.Unchecked`, meaning that it has no\nconstraint or symbol, and should be ignored in validation). In practice, this can reliably support the majority of\napplied linear algebra / ML use cases. Support for symbolic algebra for shape variables (represented\nby `shapesafe.core.arity.Var`) will be gradually enabled in future releases.\n\n##### Upgrade to Scala 3\n\nMost features in shapeless \u0026 singleton-ops are taken over by native compiler features:\n\n- shapeless.Witness → singleton type\n- shapeless.Poly → polymorphic function\n- singleton.ops.== → inline conditions \u0026 matches\n- singleton.ops._ → scala.compiletime.ops.*\n- shapeless.HList → Tuple\n- shapeless.record → Programmatic Structural Types\n\n... but some are still missing:\n\n- Product to Tuple conversion, plus its variants:\n  - shapeless.NatProductArgs\n  - shapeless.SingletonProductArgs\n- ecosystem: Apache Spark, CHISEL, LMS, typelevel stack, and much more\n\nScala 3/dotty appears to be vastly more capable as a \"proof assistant\", with 15~20x speed improvement over Scala 2 on\nimplicit search. This seems to indicate that shapesafe could only achieve large scale, production-grade algebraic\nverification after the upgrade is finished. At this moment (with Scala 2.13), if the implicit search on your computer is\ntoo slow, consider breaking you big operand composition into multiple small ones, and evaluate in-between as often as\npossible.\n\n##### Extra Read\n\n- Slide in SBTB2021: https://github.com/tribbloid/shapesafe-demo/raw/main/__presentations/SBTB2021/slide.pdf\n\n### Credit\n\n- [Prof. Dmytro Mitin](https://www.researchgate.net/profile/Dmytro-Mitin) at National Taras Shevchenko University of Kyiv\n- [Oron Port](https://github.com/soronpo) et al. maintainers of [singleton-ops](https://github.com/fthomas/singleton-ops)\n- [Mile Sabin](https://github.com/milessabin) et al. maintainers of [shapeless](https://github.com/milessabin/shapeless)\n- [Torsten Schmits](https://github.com/tek) et al. maintainers of [splain](https://github.com/tek/splain)\n- [Breandan Considine](https://scholar.google.ca/citations?user=bC-gapAAAAAJ), maintainer of [Kotlin∇](https://openreview.net/forum?id=SkluMSZ08H)\n\nThis project is heavily influenced by Kotlin∇ (see discussion [here](https://github.com/breandan/kotlingrad/issues/11)) and several pioneers in type-safe ML:\n\n- Evan Spark for [showing the possibility first](https://etrain.github.io/2015/05/28/type-safe-linear-algebra-in-scala)\n- Tongfei Chen et al. for [Nexus](https://github.com/ctongfei/nexus)\n- Dougal Maclaurin et al. for [Dex](https://github.com/google-research/dex-lang)\n- Prof. Austin Huang et al. for [HaskTorch](https://github.com/hasktorch/hasktorch)\n- Maxime Kjaer et al. for [tf-dotty](https://github.com/MaximeKjaer/tf-dotty)\n\nMany have answered critical questions that have guided how the project evolves:\n\n- Torsten Scholak - API, compiler, gradual typing\n- Alex Merritt - API, IR, documents\n- Cameron Rose - API\n- Arseniy Zhizhelev - Scala 3 upgrade\n- Ryan Orendorff - Automated theorem proving\n\n---\n\n$$\n\\frac{\\mathrm{S} \\mathrm{H} \\mathrm{A} \\mathrm{P} \\mathrm{E}}{\\: \\mathrm{S} \\: \\forall \\mathrm{F} \\: \\exists}\n \\: \\vee \\: 0.1.4\n$$","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftribbloid%2Fshapesafe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftribbloid%2Fshapesafe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftribbloid%2Fshapesafe/lists"}