{"id":21281505,"url":"https://github.com/oisdk/type-indexed-queues","last_synced_at":"2025-07-11T10:33:50.003Z","repository":{"id":56881152,"uuid":"87936972","full_name":"oisdk/type-indexed-queues","owner":"oisdk","description":"Queues with verified and unverified versions","archived":false,"fork":false,"pushed_at":"2017-05-01T16:41:57.000Z","size":18760,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-08-31T02:18:06.952Z","etag":null,"topics":["data-structures","dependent-types","haskell"],"latest_commit_sha":null,"homepage":"https://hackage.haskell.org/package/type-indexed-queues","language":"Haskell","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/oisdk.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}},"created_at":"2017-04-11T13:24:12.000Z","updated_at":"2020-11-06T22:33:22.000Z","dependencies_parsed_at":"2022-08-20T13:00:45.902Z","dependency_job_id":null,"html_url":"https://github.com/oisdk/type-indexed-queues","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oisdk%2Ftype-indexed-queues","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oisdk%2Ftype-indexed-queues/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oisdk%2Ftype-indexed-queues/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oisdk%2Ftype-indexed-queues/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oisdk","download_url":"https://codeload.github.com/oisdk/type-indexed-queues/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225715932,"owners_count":17512909,"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":["data-structures","dependent-types","haskell"],"created_at":"2024-11-21T10:48:35.498Z","updated_at":"2024-11-21T10:48:36.125Z","avatar_url":"https://github.com/oisdk.png","language":"Haskell","funding_links":[],"categories":[],"sub_categories":[],"readme":"# type-indexed-queues\n## Queues and Heaps with verified and unverified versions.\n\n[![Hackage](https://img.shields.io/hackage/v/type-indexed-queues.svg)](https://hackage.haskell.org/package/type-indexed-queues) [![Build Status](https://travis-ci.org/oisdk/type-indexed-queues.svg?branch=master)](https://travis-ci.org/oisdk/type-indexed-queues)\n\nThis library provides implementations of six different heaps\n(binomial, pairing, skew, splay, leftist, and Braun), each in two\nflavours: one verified, and one not.\n\nAt the moment, only structural invariants are maintained.\n\nMore information, and a walkthrough of a couple implementations, can be found at this [blog post](http://doisinkidney.com/posts/2017-04-23-verifying-data-structures-in-haskell-lhs.html).\n\n## Comparisons of verified and unverified heaps\nBoth versions of each heap are provided for comparison: for\ninstance, compare the standard leftist heap (in\nData.Heap.Leftist):\n\n```haskell\ndata Leftist a\n  = Leaf\n  | Node !Int\n        a\n        (Leftist a)\n        (Leftist a)\n```\n\nTo its size-indexed counterpart (in Data.Heap.Indexed.Leftist):\n\n```haskell\ndata Leftist n a where\n        Leaf :: Leftist 0 a\n        Node :: !(The Nat (n + m + 1))\n             -\u003e a\n             -\u003e Leftist n a\n             -\u003e Leftist m a\n             -\u003e !(m \u003c= n)\n             -\u003e Leftist (n + m + 1) a\n```\n\nThe invariant here (that the size of the left heap must\nalways be less than that of the right) is encoded in the\nproof `m \u003c= n`.\n \nWith that in mind, compare the unverified and verified\nimplementatons of `merge`:\n\n```haskell\nmerge Leaf h2 = h2\nmerge h1 Leaf = h1\nmerge h1@(Node w1 p1 l1 r1) h2@(Node w2 p2 l2 r2)\n  | p1 \u003c p2 =\n      if ll \u003c= lr\n          then Node (w1 + w2) p1 l1 (merge r1 h2)\n          else Node (w1 + w2) p1 (merge r1 h2) l1\n  | otherwise =\n      if rl \u003c= rr\n          then Node (w1 + w2) p2 l2 (merge r2 h1)\n          else Node (w1 + w2) p2 (merge r2 h1) l2\n  where\n    ll = rank r1 + w2\n    lr = rank l1\n    rl = rank r2 + w1\n    rr = rank l2\n```\n\nVerified:\n\n```haskell\nmerge Leaf h2 = h2\nmerge h1 Leaf = h1\nmerge h1@(Node w1 p1 l1 r1 _) h2@(Node w2 p2 l2 r2 _)\n  | p1 \u003c p2 =\n      if ll \u003c=. lr\n        then Node (w1 +. w2) p1 l1 (merge r1 h2)\n        else Node (w1 +. w2) p1 (merge r1 h2) l1 . totalOrder ll lr\n  | otherwise =\n      if rl \u003c=. rr\n          then Node (w1 +. w2) p2 l2 (merge r2 h1)\n          else Node (w1 +. w2) p2 (merge r2 h1) l2 . totalOrder rl rr\n  where\n    ll = rank r1 +. w2\n    lr = rank l1\n    rl = rank r2 +. w1\n    rr = rank l2\n```\n\n## Using type families and typechecker plugins to encode the invariants\nThe similarity is accomplished through overloading, and some\nhandy functions. For instance, the second if-then-else works\non boolean *singletons*, and the `\u003c=.` function provides a\nproof of order along with its answer. The actual arithmetic\nis carried out at runtime on normal integers, rather than\nPeano numerals. These tricks are explained in more detail\nTypeLevel.Singletons and TypeLevel.Bool.\n\nA typechecker plugin does most of the heavy lifting, although\nthere are some (small) manual proofs.\n\n## Uses of verified heaps\nThe main interesting use of these sturctures is total traversable\nsorting ([sort-traversable](https://github.com/treeowl/sort-traversable)).\nAn implementation of this is provided in Data.Traversable.Parts. I'm\ninterested in finding out other uses for these kinds of structures.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foisdk%2Ftype-indexed-queues","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foisdk%2Ftype-indexed-queues","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foisdk%2Ftype-indexed-queues/lists"}