#布尔 #逻辑 #迭代器 #产品 #真值表

无 std truth-values

生成 N 个布尔值的所有可能组合

1 个不稳定版本

0.1.0 2024 年 4 月 16 日

557算法

MIT 许可证

52KB
592

truth-values

CI Latest Version Docs License

小巧、无依赖、无分配*,用于生成 n 个 bool 值的所有可能组合的 no_std 库。适用于测试 布尔函数、验证 逻辑等价 和生成 真值表*可选的 alloc 功能用于与 Vec 相关的功能。

示例 - each()each_const()

考虑实现一个解释器或优化器,现在你想断言表达式之间的 逻辑等价,例如断言 德摩根定律

  • not (A or B) = (not A) and (not B)
  • not (A and B) = (not A) or (not B)

使用 const 泛型变体,即 N 是常量

each_const(|[a, b]| {
    assert_eq!(!(a || b), !a && !b);
    assert_eq!(!(a && b), !a || !b);
});
// The closure is called for each combination of 2 `bool`s, i.e.:
// [false, false]
// [true,  false]
// [false, true]
// [true,  true]

使用 非 const 泛型变体,即 n 可以是动态的

each(2, |bools| match bools {
    &[a, b] => {
        assert_eq!(!(a || b), !a && !b);
        assert_eq!(!(a && b), !a || !b);
    }
    _ => unreachable!(),
});
// The closure is called for each combination of 2 `bool`s, i.e.:
// &[false, false]
// &[true,  false]
// &[false, true]
// &[true,  true]

示例 - gen()gen_const()

或者,使用 gen() 函数 获取一个用于生成所有组合的 Iterator。这可以用于例如将每个组合映射到一个 Expr,以便于生成所有 Expr 组合以验证其评估。

使用 const 泛型变体,即 N 是常量

#[derive(PartialEq, Debug)]
enum Expr {
    Bool(bool),
    And(Box<Self>, Box<Self>),
    // ...
}

impl Expr {
    fn and(lhs: Expr, rhs: Expr) -> Expr {
        Expr::And(Box::new(lhs), Box::new(rhs))
    }
}

let exprs = truth_values::gen_const()
    .map(|[a, b]| {
        Expr::and(Expr::Bool(a), Expr::Bool(b))
    })
    .collect::<Vec<_>>();

assert_eq!(
    exprs,
    [
        Expr::and(Expr::Bool(false), Expr::Bool(false)),
        Expr::and(Expr::Bool(true),  Expr::Bool(false)),
        Expr::and(Expr::Bool(false), Expr::Bool(true)),
        Expr::and(Expr::Bool(true),  Expr::Bool(true)),
    ]
);

使用 非 const 泛型变体,即 n 可以是动态的

let exprs = truth_values::gen_slice(2, |bools| {
    match bools {
        &[a, b] => {
            Expr::and(Expr::Bool(a), Expr::Bool(b))
        }
        _ => unreachable!(),
    }
})
.collect::<Vec<_>>();

assert_eq!(
    exprs,
    [
        Expr::and(Expr::Bool(false), Expr::Bool(false)),
        Expr::and(Expr::Bool(true),  Expr::Bool(false)),
        Expr::and(Expr::Bool(false), Expr::Bool(true)),
        Expr::and(Expr::Bool(true),  Expr::Bool(true)),
    ]
);

4 个布尔值(bool)的组合

gen_const::<1>()
gen_const::<2>()
gen_const::<3>()
gen_const::<4>()
[false]
[true]
[false, false]
[true,  false]
[false, true]
[true,  true]
[false, false, false]
[true,  false, false]
[false, true,  false]
[true,  true,  false]
[false, false, true]
[true,  false, true]
[false, true,  true]
[true,  true,  true]
[false, false, false, false]
[true,  false, false, false]
[false, true,  false, false]
[true,  true,  false, false]
[false, false, true,  false]
[true,  false, true,  false]
[false, true,  true,  false]
[true,  true,  true,  false]
[false, false, false, true]
[true,  false, false, true]
[false, true,  false, true]
[true,  true,  false, true]
[false, false, true,  true]
[true,  false, true,  true]
[false, true,  true,  true]
[true,  true,  true,  true]

实现

gen() 函数返回一个 Iterator,它还特别实现了 size_hint()count()nth()last()

Iterator 还实现了

警告

组合的数量是指数级的!N 个布尔变量的组合数是 2N。简而言之,10 个变量 产生 1024 种组合,但 20 个变量 产生超过 100 万种组合

仅用生成器穷举 30 个变量,即超过 10 亿种组合,在我的机器上只需要几秒钟。

理想情况下,如果用于测试表达式,那么可能只有少数几个变量。然而,如果接受用户输入,那么可能值得保护和限制变量的数量。

因此,尽管支持 64 位平台上的最多 MAX63)个变量,但尝试处理那么多变量可能并不理想。

无运行时依赖

功能