{"id":16856397,"url":"https://github.com/vallentin/truth-values","last_synced_at":"2025-03-18T11:14:17.952Z","repository":{"id":233420994,"uuid":"786571188","full_name":"vallentin/truth-values","owner":"vallentin","description":null,"archived":false,"fork":false,"pushed_at":"2024-04-16T03:48:45.000Z","size":17,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-28T04:29:10.178Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","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/vallentin.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,"publiccode":null,"codemeta":null}},"created_at":"2024-04-14T21:20:39.000Z","updated_at":"2024-04-16T03:34:08.000Z","dependencies_parsed_at":null,"dependency_job_id":"e356c00e-8980-46a3-908a-447185188c38","html_url":"https://github.com/vallentin/truth-values","commit_stats":null,"previous_names":["vallentin/truth-values"],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vallentin%2Ftruth-values","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vallentin%2Ftruth-values/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vallentin%2Ftruth-values/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vallentin%2Ftruth-values/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vallentin","download_url":"https://codeload.github.com/vallentin/truth-values/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244207746,"owners_count":20416109,"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":[],"created_at":"2024-10-13T14:04:07.251Z","updated_at":"2025-03-18T11:14:17.947Z","avatar_url":"https://github.com/vallentin.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# truth-values\n\n[![CI](https://github.com/vallentin/truth-values/workflows/CI/badge.svg)](https://github.com/vallentin/truth-values/actions?query=workflow%3ACI)\n[![Latest Version](https://img.shields.io/crates/v/truth-values.svg)](https://crates.io/crates/truth-values)\n[![Docs](https://docs.rs/truth-values/badge.svg)](https://docs.rs/truth-values)\n[![License](https://img.shields.io/github/license/vallentin/truth-values.svg)](https://github.com/vallentin/truth-values)\n\n\u003c!-- cargo-rdme start --\u003e\n\nTiny, zero-dependency, zero-allocation*, `no_std` library for generating all possible\ncombinations of `n` [`bool`]s. Useful for testing [boolean functions],\nverifying [logical equivalence], and generating [truth tables].\n_\\*Optional `alloc` feature for [`Vec`] related functions._\n\n[boolean functions]: https://en.wikipedia.org/wiki/Boolean_function\n[logical equivalence]: https://en.wikipedia.org/wiki/Logical_equivalence\n[truth tables]: https://en.wikipedia.org/wiki/Truth_table\n\n## Example - `each()` and `each_const()`\n\nConsider implementing an interpreter or optimizer, and now you\nwant to assert [logical equivalence] between expressions, e.g.\nasserting [De Morgan's laws]:\n\n- not (A or B)  = (not A) and (not B)\n- not (A and B) = (not A) or (not B)\n\n[De Morgan's laws]: https://en.wikipedia.org/wiki/De_Morgan%27s_laws\n\nUsing [const generic variant](https://docs.rs/truth-values/latest/truth_values/fn.each_const.html), i.e. where `N` is const:\n\n```rust\neach_const(|[a, b]| {\n    assert_eq!(!(a || b), !a \u0026\u0026 !b);\n    assert_eq!(!(a \u0026\u0026 b), !a || !b);\n});\n// The closure is called for each combination of 2 `bool`s, i.e.:\n// [false, false]\n// [true,  false]\n// [false, true]\n// [true,  true]\n```\n\nUsing [non-const generic variant](https://docs.rs/truth-values/latest/truth_values/fn.each.html), i.e. where `n` can be dynamic:\n\n```rust\neach(2, |bools| match bools {\n    \u0026[a, b] =\u003e {\n        assert_eq!(!(a || b), !a \u0026\u0026 !b);\n        assert_eq!(!(a \u0026\u0026 b), !a || !b);\n    }\n    _ =\u003e unreachable!(),\n});\n// The closure is called for each combination of 2 `bool`s, i.e.:\n// \u0026[false, false]\n// \u0026[true,  false]\n// \u0026[false, true]\n// \u0026[true,  true]\n```\n\n## Example - `gen()` and `gen_const()`\n\nAlternatively, use [`gen()` functions](https://docs.rs/truth-values/latest/truth_values/#functions) to obtain\nan [`Iterator`] for generating all combinations. This could be used\nto e.g. map each combination into an `Expr` for an [AST], to easily\ngenerate all `Expr` combinations to verify their evaluation.\n\n[AST]: https://en.wikipedia.org/wiki/Abstract_syntax_tree\n\nUsing [const generic variant](https://docs.rs/truth-values/latest/truth_values/fn.gen_const.html), i.e. where `N` is const:\n\n```rust\n#[derive(PartialEq, Debug)]\nenum Expr {\n    Bool(bool),\n    And(Box\u003cSelf\u003e, Box\u003cSelf\u003e),\n    // ...\n}\n\nimpl Expr {\n    fn and(lhs: Expr, rhs: Expr) -\u003e Expr {\n        Expr::And(Box::new(lhs), Box::new(rhs))\n    }\n}\n\nlet exprs = truth_values::gen_const()\n    .map(|[a, b]| {\n        Expr::and(Expr::Bool(a), Expr::Bool(b))\n    })\n    .collect::\u003cVec\u003c_\u003e\u003e();\n\nassert_eq!(\n    exprs,\n    [\n        Expr::and(Expr::Bool(false), Expr::Bool(false)),\n        Expr::and(Expr::Bool(true),  Expr::Bool(false)),\n        Expr::and(Expr::Bool(false), Expr::Bool(true)),\n        Expr::and(Expr::Bool(true),  Expr::Bool(true)),\n    ]\n);\n```\n\nUsing [non-const generic variant](https://docs.rs/truth-values/latest/truth_values/fn.gen_slice.html), i.e. where `n` can be dynamic:\n\n```rust\nlet exprs = truth_values::gen_slice(2, |bools| {\n    match bools {\n        \u0026[a, b] =\u003e {\n            Expr::and(Expr::Bool(a), Expr::Bool(b))\n        }\n        _ =\u003e unreachable!(),\n    }\n})\n.collect::\u003cVec\u003c_\u003e\u003e();\n\nassert_eq!(\n    exprs,\n    [\n        Expr::and(Expr::Bool(false), Expr::Bool(false)),\n        Expr::and(Expr::Bool(true),  Expr::Bool(false)),\n        Expr::and(Expr::Bool(false), Expr::Bool(true)),\n        Expr::and(Expr::Bool(true),  Expr::Bool(true)),\n    ]\n);\n```\n\n## Combinations of 1, 2, 3, 4 `bool`s\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd style=\"text-align: center;\"\u003e\n\n```rust\ngen_const::\u003c1\u003e()\n```\n\n\u003c/td\u003e\n\u003ctd style=\"text-align: center;\"\u003e\n\n```rust\ngen_const::\u003c2\u003e()\n```\n\n\u003c/td\u003e\n\u003ctd style=\"text-align: center;\"\u003e\n\n```rust\ngen_const::\u003c3\u003e()\n```\n\n\u003c/td\u003e\n\u003ctd style=\"text-align: center;\"\u003e\n\n```rust\ngen_const::\u003c4\u003e()\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr\u003e\n\u003ctd style=\"vertical-align: top;\"\u003e\n\n```rust\n[false]\n[true]\n```\n\n\u003c/td\u003e\n\u003ctd style=\"vertical-align: top;\"\u003e\n\n```rust\n[false, false]\n[true,  false]\n[false, true]\n[true,  true]\n```\n\n\u003c/td\u003e\n\u003ctd style=\"vertical-align: top;\"\u003e\n\n```rust\n[false, false, false]\n[true,  false, false]\n[false, true,  false]\n[true,  true,  false]\n[false, false, true]\n[true,  false, true]\n[false, true,  true]\n[true,  true,  true]\n```\n\n\u003c/td\u003e\n\u003ctd style=\"vertical-align: top;\"\u003e\n\n```rust\n[false, false, false, false]\n[true,  false, false, false]\n[false, true,  false, false]\n[true,  true,  false, false]\n[false, false, true,  false]\n[true,  false, true,  false]\n[false, true,  true,  false]\n[true,  true,  true,  false]\n[false, false, false, true]\n[true,  false, false, true]\n[false, true,  false, true]\n[true,  true,  false, true]\n[false, false, true,  true]\n[true,  false, true,  true]\n[false, true,  true,  true]\n[true,  true,  true,  true]\n```\n\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n## Implementation\n\nThe [`gen()` functions](https://docs.rs/truth-values/latest/truth_values/#functions) return an [`Iterator`], which\nadditionally specializes [`size_hint()`], [`count()`], [`nth()`], [`last()`].\n\nThe [`Iterator`] also implements:\n\n- [`DoubleEndedIterator`] implementing [`next_back()`] and [`nth_back()`]\n- [`ExactSizeIterator`] implementing [`len()`]\n- [`FusedIterator`]\n\n## Warning\n\nThe amount of combinations is exponential!\nThe number of combinations for `N` boolean variables is \u003ccode\u003e2\u003csup\u003eN\u003c/sup\u003e\u003c/code\u003e.\nIn short, **10 variables** produce **1024 combinations**, but **20 variables**\nproduce over **1 million combinations**.\n\n_Just alone exhausting the generator for **30 variables**, i.e. over **1 billion\ncombinations**, takes a handful of seconds on my machine._\n\nIdeally, if used to test expressions, then there will likely only be a handful of\nvariables. However, if user input is accepted, then it might be worth guarding and\nlimiting the number of variables.\n\nSo even though up to [`MAX`] (`63`) variables for 64-bit platforms\nis supported, it is probably undesirable to even attempt to process\nthat many variables.\n\n[`MAX`]: https://docs.rs/truth-values/latest/truth_values/const.MAX.html\n\n[`size_hint()`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.size_hint\n[`count()`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.count\n[`nth()`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.nth\n[`last()`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.last\n[`next_back()`]: https://doc.rust-lang.org/std/iter/trait.DoubleEndedIterator.html#tymethod.next_back\n[`nth_back()`]: https://doc.rust-lang.org/std/iter/trait.DoubleEndedIterator.html#method.nth_back\n[`len()`]: https://doc.rust-lang.org/std/iter/trait.ExactSizeIterator.html#method.len\n\n\u003c!-- cargo-rdme end --\u003e\n\n[`bool`]: https://doc.rust-lang.org/std/primitive.bool.html\n[`Vec`]: https://doc.rust-lang.org/std/vec/struct.Vec.html\n[`Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html\n[`DoubleEndedIterator`]: https://doc.rust-lang.org/std/iter/trait.DoubleEndedIterator.html\n[`ExactSizeIterator`]: https://doc.rust-lang.org/std/iter/trait.ExactSizeIterator.html\n[`FusedIterator`]: https://doc.rust-lang.org/std/iter/trait.FusedIterator.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvallentin%2Ftruth-values","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvallentin%2Ftruth-values","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvallentin%2Ftruth-values/lists"}