flipspec

    Finite-domain counterfactual planner that certifies minimum-cost decision flips

    counterfactual
    finite-domain
    minimality
    explainability
    repair-plan
    Download zip
    Version
    0.1.1
    License
    Apache-2.0
    Last updated
    2 months ago
    Downloads
    34

    No dependencies

    #FlipSpec

    不只告诉你“为什么不通过”,还告诉你“最少改什么才能通过”。

    FlipSpec 是一个使用 MoonBit 原生实现的有限域反事实规格规划器。它把准入条件、发布门禁、功能开关或配置约束写成一份小型规格,计算当前结果,并在声明的可行取值域中寻找最低代价的结果翻转方案。

    普通校验器通常只返回 true 或 false;FlipSpec 同时返回:

    • 保留“未知”的三值逻辑结果,避免把缺失数据误判为 false;
    • 可逐层追踪的解释树和真正阻断结果的叶节点;
    • 按修改代价、修改数量和稳定顺序排列的反事实修复方案;
    • 单变量敏感性探测和完整决策表;
    • 表达式化简、否定范式、批量场景回归和全局特征影响度;
    • 模型 lint 与外部修复方案防篡改复核;
    • 穷尽搜索后的最小性证书,说明最低代价方案是否可被独立复核;
    • 预算曲线、模型画像和修复组合分析,帮助评估规格规模与修复前沿;
    • Markdown、JSON、Mermaid 三种无需额外依赖的导出格式。

    #适用场景

    • 发布门禁:覆盖率、签名、区域和稳定性满足什么条件才能上线;
    • 账号或资源准入:哪些最小资料补充能使申请通过;
    • 功能开关:哪些配置组合会改变功能状态;
    • CI 策略:失败的质量门需要修改哪些指标;
    • 教学与复盘:用解释树展示复合布尔表达式如何得到最终结论。

    FlipSpec 处理的是有限、可枚举、需要解释的策略模型,不是通用 SAT/SMT 求解器,也不执行任意用户代码。

    #安装

    Mooncakes 包标识为 yourenA1108/flipspec,当前公开仓库为 https://github.com/yourenA1108/flipspec。

    发布后可通过以下命令添加依赖:

    moon add yourenA1108/flipspec@0.1.1

    也可以克隆源码直接验收:

    git clone https://github.com/yourenA1108/flipspec.git cd flipspec moon check moon build moon test

    #五分钟上手

    一份 FlipSpec 由规格名称、特征和目标表达式组成:

    spec release-readiness feature coverage = 72 in [72, 80, 90] cost 2 feature flaky = true in [true, false] cost 4 feature region = "cn" in ["cn", "global"] cost 3 feature signed = true in [true] locked goal coverage >= 80 and not flaky and region == "global" and signed

    • = 后是当前值;
    • in [...] 是允许搜索的可行取值域;
    • cost 是修改该特征一次的代价,默认为 1;
    • locked 表示该事实参与判断但不能被修复方案修改;
    • 布尔特征可直接写成 signed,等价于 signed == true。

    在 MoonBit 代码中解析、解释并规划:

    let source =
    #|spec gate
    #|feature coverage = 72 in [72, 80, 90] cost 2
    #|feature signed = true in [true] locked
    #|goal coverage >= 80 and signed

    match @flipspec.parse(source) {
    Err(error) => println(error.render())
    Ok(model) => {
    println(model.evaluate().trace.to_text())
    match model.plan() {
    Ok(plan) => println(plan.to_markdown())
    Err(errors) => println("invalid model: \{errors.length()} error(s)")
    }
    }
    }

    #可运行示例

    仓库内置的示例不依赖文件系统,因此可以在 MoonBit 的 Wasm 默认目标直接复现:

    # 解释当前决定并打印最低代价修复方案 moon run cmd/main # 机器可读输出 moon run cmd/main -- --json # Mermaid 解释图 moon run cmd/main -- --mermaid # 单变量敏感性探测 moon run cmd/main -- --probe # 最小性证书:证明示例中的最低代价方案来自完整搜索 moon run cmd/main -- --certificate moon run cmd/main -- --certificate --json # 预算曲线、模型画像和修复组合分析 moon run cmd/main -- --budget moon run cmd/main -- --profile moon run cmd/main -- --portfolio

    示例的当前状态为 false,最低修复代价是 9:覆盖率至少提高到 80、消除 flaky 状态,并把区域切换到 global。单独修改其中任意一项仍然失败,这正是全局反事实搜索区别于普通字段校验的地方。

    #核心功能与 API

    能力主要 API说明
    DSL 解析parse带行列号和稳定错误码的词法、语法与模型校验
    三值求值evaluate、Policy::evaluateYes、No、Unknown 的 Kleene 逻辑
    解释Trace::to_text、blocking_leaves递归原因树与阻断条件前沿
    反事实规划Policy::plan有界穷举、代价排序、支配方案消除
    局部敏感性Policy::probe测试每个单变量修改是否翻转结果
    决策面Policy::decision_table枚举可行组合,支持显式行数上限
    表达式工具stats、simplify、to_nnf、substitute结构指标、等价化简和部分求值
    批量回归evaluate_scenarios、diff_environments比较命名场景与当前基线
    全局影响度Policy::impact_report在决策面上统计每个特征改变结果的次数
    模型检查Policy::lint未使用特征、重复域值、恒真或永不为真等提示
    修复复核Policy::verify_repair复核外部修复的域、锁定、成本、新鲜度和结果
    最小性证书Plan::certify、Policy::search_space_size记录可行赋值总数、求值数、截断状态和最低代价是否已被穷尽搜索确认
    预算曲线Policy::budget_report统计不同预算下的可达赋值、目标赋值与最低成功预算
    模型画像Policy::profile汇总搜索空间、表达式复杂度、特征状态和可维护性信号
    修复组合分析Plan::portfolio找出所有候选修复的共识特征、替代值和变更负担
    导出to_markdown、to_json、to_mermaid零第三方运行时依赖
    往返编辑Policy::to_source程序化模型序列化为可再次解析的 DSL

    公开类型与函数的精确签名见生成的 pkg.generated.mbti。

    #DSL 支持范围

    当前支持:

    • Int、Bool、String 三种标量;
    • ==、!=、<、<=、>、>=;
    • and、or、not 和括号;
    • present(name) 存在性判断;
    • # 行注释、字符串转义、负整数;
    • 每个特征的有限取值域、非负修改代价和锁定标记;
    • 搜索结果数量与最大求值次数上限。

    暂不支持:

    • 浮点数、集合、日期或用户自定义函数;
    • 从 DSL 调用网络、文件系统或宿主语言代码;
    • 连续空间优化、概率模型、SAT/SMT 约束;
    • 自动判断现实世界中一次修改是否真正可执行;可行域必须由调用者明确声明。

    #搜索语义与边界

    若当前结果是 false,规划目标是 true;若当前结果是 true,规划目标是 false;若当前结果是 unknown,默认寻找变成 true 的方案。每个发生变化的特征按其 cost 计费一次。

    搜索空间是未锁定特征域大小的乘积。PlanOptions::max_evaluations 默认限制为 10000,超过上限会将 truncated 标记为 true,而不是假装搜索完整。该设计适合几十个小域特征的可解释策略,不适合巨大组合优化问题。算法和不变量详见 docs/DESIGN.md。

    #本地验收

    moon check moon build moon test moon run cmd/main moon run cmd/main -- --json moon run cmd/main -- --certificate moon run cmd/main -- --budget moon publish --dry-run

    60 项自动测试包含正常输入、错误输入、边界值、整数溢出、字符串转义、运算符优先级、模型转换、三值逻辑、全局搜索、锁定变量、搜索截断、最小性证书、预算曲线、模型画像、修复组合分析、表达式变换、批量场景、特征影响度、修复复核、决策表和三种导出格式。CI 在每次 push 和 pull request 中执行检查、构建、全部测试和示例 smoke test。

    #工程结构

    . ├── model.mbt # 数据模型、三值逻辑与模型校验 ├── lexer.mbt # 带位置的 DSL 词法分析 ├── parser.mbt # 递归下降解析器 ├── evaluate.mbt # 求值与解释树 ├── planner.mbt # 反事实搜索、排序、敏感性探测 ├── analyze.mbt # 阻断条件、决策表、DSL 序列化 ├── transform.mbt # 表达式变换、结构指标与模型 lint ├── batch.mbt # 批量场景回归和环境差异 ├── budget.mbt # 预算曲线和最低成功预算分析 ├── impact.mbt # 全决策面特征影响度 ├── profile.mbt # 模型画像、搜索规模和特征可维护性摘要 ├── portfolio.mbt # 修复组合分析和共识特征提取 ├── verify.mbt # 外部修复方案一致性复核 ├── report.mbt # Markdown / JSON / Mermaid 导出 ├── cmd/main # 可运行演示 CLI ├── flipspec_test.mbt # 黑盒行为测试 ├── flipspec_wbtest.mbt # 内部不变量测试 ├── docs # 语言、设计、调研、专项自查与发布说明 └── .github/workflows # 持续集成

    #原创性、依赖与许可证

    FlipSpec 是原创 MoonBit 项目,没有移植第三方源码或测试数据。运行时代码只使用 MoonBit 标准库,示例数据为本项目自制;仓库不包含来源不明的图片、字体、音频或二进制素材。最新查重后,项目边界进一步明确为“有限域反事实规格、最低代价结果翻转与最小性证书”,不同于通用 JSON 规则执行、项目材料审核、统计因果推断、覆盖率门禁或 Web 协议策略库。选题查重与差异说明见 docs/RESEARCH.md,初审驳回风险专项自查见 docs/REVIEW_RISK_SELF_CHECK.md,依赖合规记录见 THIRD_PARTY.md。

    项目采用 Apache License 2.0。贡献方式见 CONTRIBUTING.md,版本变化见 CHANGELOG.md。

    Environment

    type Environment = Array[Binding]

    An Array is a collection of values that supports random access and can grow in size.

    BatchResult

    pub(all) struct BatchResult {
    policy_name : String
    baseline : Truth
    scenarios : Array[ScenarioResult]
    } derive(Eq,
    Debug
    )

    BatchResult::changed

    BatchResult::to_markdown

    fn BatchResult::to_markdown(self : BatchResult) -> String

    Binding

    pub(all) struct Binding {
    name : String
    value : Value
    } derive(Eq,
    Debug
    )

    A lightweight ordered environment. Arrays keep reports deterministic across compilation targets and are sufficient for the small policy models FlipSpec is designed to explain.

    BudgetPoint

    pub(all) struct BudgetPoint {
    budget : Int
    assignments : Int
    target_assignments : Int
    yes : Int
    no : Int
    unknown : Int
    cheapest_target_cost : Int
    } derive(Eq,
    Debug
    )

    BudgetPoint::has_target

    fn BudgetPoint::has_target(self : BudgetPoint) -> Bool

    BudgetPoint::target_per_mille

    fn BudgetPoint::target_per_mille(self : BudgetPoint) -> Int

    BudgetPoint::target_ratio

    fn BudgetPoint::target_ratio(self : BudgetPoint) -> String

    BudgetReport

    pub(all) struct BudgetReport {
    policy_name : String
    baseline : Truth
    target : Truth
    max_budget : Int
    domain_points : Int
    evaluated : Int
    outside_budget : Int
    truncated : Bool
    points : Array[BudgetPoint]
    } derive(Eq,
    Debug
    )

    BudgetReport::complete

    fn BudgetReport::complete(self : BudgetReport) -> Bool

    BudgetReport::minimum_budget

    fn BudgetReport::minimum_budget(self : BudgetReport) -> Int

    BudgetReport::point_for

    fn BudgetReport::point_for(self : BudgetReport, budget : Int) -> BudgetPoint?

    BudgetReport::to_json

    fn BudgetReport::to_json(self : BudgetReport) -> String

    BudgetReport::to_markdown

    fn BudgetReport::to_markdown(self : BudgetReport) -> String

    Change

    pub(all) struct Change {
    feature : String
    from : Value
    to : Value
    cost : Int
    } derive(Eq,
    Debug
    )

    Change::render

    fn Change::render(self : Change) -> String

    CompareOp

    pub(all) enum CompareOp {
    Equal
    NotEqual
    Less
    LessEqual
    Greater
    GreaterEqual
    } derive(Eq,
    Debug
    )

    CompareOp::render

    fn CompareOp::render(self : CompareOp) -> String

    DecisionRow

    pub(all) struct DecisionRow {
    environment : Array[Binding]
    outcome : Truth
    } derive(Eq,
    Debug
    )

    DecisionTable

    pub(all) struct DecisionTable {
    policy_name : String
    rows : Array[DecisionRow]
    combinations : Int
    truncated : Bool
    } derive(Eq,
    Debug
    )

    DecisionTable::count

    fn DecisionTable::count(self : DecisionTable, truth : Truth) -> Int

    DecisionTable::to_markdown

    fn DecisionTable::to_markdown(self : DecisionTable) -> String

    Diagnostic

    pub(all) struct Diagnostic {
    code : String
    message : String
    span : Span
    } derive(Eq,
    Debug
    )

    A human-readable, structured error. FlipSpec returns diagnostics instead of aborting so callers can render them in a CLI, editor, or web application.

    Diagnostic::render

    fn Diagnostic::render(self : Diagnostic) -> String

    EnvironmentChange

    pub(all) struct EnvironmentChange {
    name : String
    before : Value?
    after : Value?
    } derive(Eq,
    Debug
    )

    Evaluation

    pub(all) struct Evaluation {
    truth : Truth
    trace : Trace
    } derive(Eq,
    Debug
    )

    Expr

    pub(all) enum Expr {
    Constant(Truth)
    Compare(String, CompareOp, Value)
    Present(String)
    Not(Expr)
    And(Expr, Expr)
    Or(Expr, Expr)
    } derive(Eq,
    Debug
    )

    Boolean expression evaluated against a set of named feature values.

    Expr::render

    fn Expr::render(self : Expr) -> String

    Expr::simplify

    fn Expr::simplify(self : Expr) -> Expr

    Fold boolean constants, duplicate branches, and double negation without changing three-valued semantics.

    Expr::stats

    fn Expr::stats(self : Expr) -> ExpressionStats

    Expr::substitute

    fn Expr::substitute(self : Expr, name : String, value : Value) -> Expr

    Partially evaluate all predicates that reference a supplied feature.

    Expr::to_nnf

    fn Expr::to_nnf(self : Expr) -> Expr

    Convert to negation-normal form, leaving not only directly above atomic predicates. This is useful for rule editors and visualizers.

    ExpressionStats

    pub(all) struct ExpressionStats {
    nodes : Int
    depth : Int
    comparisons : Int
    variables : Array[String]
    } derive(Eq,
    Debug
    )

    Feature

    pub(all) struct Feature {
    name : String
    current : Value
    domain : Array[Value]
    cost : Int
    locked : Bool
    } derive(Eq,
    Debug
    )

    A feature includes its current value, its feasible domain, and an integer edit cost. Locked features participate in evaluation but never in repairs.

    FeatureImpact

    pub(all) struct FeatureImpact {
    feature : String
    transitions : Int
    outcome_flips : Int
    flips_to_true : Int
    flips_to_false : Int
    unknown_transitions : Int
    } derive(Eq,
    Debug
    )

    FeatureProfile

    pub(all) struct FeatureProfile {
    name : String
    value_kind : String
    domain_size : Int
    mutable_values : Int
    current_index : Int
    cost : Int
    locked : Bool
    referenced : Bool
    duplicate_values : Int
    } derive(Eq,
    Debug
    )

    FeatureProfile::actionable

    fn FeatureProfile::actionable(self : FeatureProfile) -> Bool

    FeatureProfile::label

    fn FeatureProfile::label(self : FeatureProfile) -> String

    ImpactReport

    pub(all) struct ImpactReport {
    policy_name : String
    impacts : Array[FeatureImpact]
    source_rows : Int
    truncated : Bool
    } derive(Eq,
    Debug
    )

    ImpactReport::to_markdown

    fn ImpactReport::to_markdown(self : ImpactReport) -> String

    LintFinding

    pub(all) struct LintFinding {
    code : String
    severity : LintSeverity
    message : String
    feature : String?
    } derive(Eq,
    Debug
    )

    LintSeverity

    pub(all) enum LintSeverity {
    Info
    Warning
    } derive(Eq,
    Debug
    )

    ModelProfile

    pub(all) struct ModelProfile {
    policy_name : String
    features : Array[FeatureProfile]
    goal_variables : Array[String]
    expression_nodes : Int
    expression_depth : Int
    comparisons : Int
    mutable_features : Int
    locked_features : Int
    zero_cost_mutable : Int
    singleton_domains : Int
    duplicate_domain_values : Int
    search_space : Int
    } derive(Eq,
    Debug
    )

    ModelProfile::actionable_features

    fn ModelProfile::actionable_features(self : ModelProfile) -> Array[String]

    ModelProfile::locked_referenced_features

    fn ModelProfile::locked_referenced_features(self : ModelProfile) -> Array[String]

    ModelProfile::to_json

    fn ModelProfile::to_json(self : ModelProfile) -> String

    ModelProfile::to_markdown

    fn ModelProfile::to_markdown(self : ModelProfile) -> String

    ModelProfile::unreferenced_features

    fn ModelProfile::unreferenced_features(self : ModelProfile) -> Array[String]

    Plan

    pub(all) struct Plan {
    policy_name : String
    baseline : Truth
    target : Truth
    repairs : Array[Repair]
    evaluated : Int
    truncated : Bool
    } derive(Eq,
    Debug
    )

    Plan::certify

    fn Plan::certify(self : Plan, model : Policy) -> PlanCertificate

    Plan::portfolio

    fn Plan::portfolio(self : Plan) -> RepairPortfolio

    Plan::to_json

    fn Plan::to_json(self : Plan) -> String

    Plan::to_markdown

    fn Plan::to_markdown(self : Plan) -> String

    PlanCertificate

    pub(all) struct PlanCertificate {
    policy_name : String
    baseline : Truth
    target : Truth
    domain_points : Int
    assignments_evaluated : Int
    search_exhaustive : Bool
    output_truncated : Bool
    has_repair : Bool
    best_cost : Int
    lower_cost_excluded : Bool
    status : String
    } derive(Eq,
    Debug
    )

    PlanCertificate::to_json

    fn PlanCertificate::to_json(self : PlanCertificate) -> String

    PlanCertificate::to_markdown

    fn PlanCertificate::to_markdown(self : PlanCertificate) -> String

    PlanOptions

    pub(all) struct PlanOptions {
    max_results : Int
    max_evaluations : Int
    } derive(Eq,
    Debug
    )

    Policy

    pub(all) struct Policy {
    name : String
    features : Array[Feature]
    goal : Expr
    } derive(Eq,
    Debug
    )

    Policy::budget_report

    fn Policy::budget_report(self : Policy, max_budget? : Int, max_evaluations? : Int) -> Result[BudgetReport, Diagnostic]

    Policy::decision_table

    fn Policy::decision_table(self : Policy, limit? : Int) -> Result[DecisionTable, Diagnostic]

    Enumerate the feasible decision surface. Mutable feature domains are expanded; locked features stay at their current value. limit bounds the materialized rows so the API is safe for interactive tools.

    Policy::environment

    fn Policy::environment(self : Policy) -> Array[Binding]

    Policy::evaluate

    fn Policy::evaluate(self : Policy) -> Evaluation

    Policy::evaluate_scenarios

    fn Policy::evaluate_scenarios(self : Policy, scenarios : Array[Scenario]) -> BatchResult

    Evaluate named environments as a deterministic regression suite.

    Policy::find_feature

    fn Policy::find_feature(self : Policy, name : String) -> Feature?

    Policy::impact_report

    fn Policy::impact_report(self : Policy, table_limit? : Int) -> Result[ImpactReport, Diagnostic]

    Measure how often changing one feature changes the outcome across a bounded decision table. Counts are directional and therefore suitable for ranking, not probability estimates.

    Policy::lint

    fn Policy::lint(self : Policy, table_limit? : Int) -> Array[LintFinding]

    Policy::plan

    fn Policy::plan(self : Policy, options? : PlanOptions) -> Result[Plan, Array[Diagnostic]]

    Find the cheapest feasible ways to flip a policy's current outcome. A false outcome targets true, a true outcome targets false, and an unknown outcome targets true so missing/invalid states receive an actionable path forward.

    Policy::probe

    fn Policy::probe(self : Policy) -> Array[Probe]

    Policy::profile

    fn Policy::profile(self : Policy) -> ModelProfile

    Policy::search_space_size

    fn Policy::search_space_size(self : Policy) -> Int

    Policy::to_source

    fn Policy::to_source(self : Policy) -> String

    Serialize a programmatically assembled policy back to canonical FlipSpec. The result can be parsed again, which makes it useful for editors and model migration tools.

    Policy::unused_features

    fn Policy::unused_features(self : Policy) -> Array[String]

    Policy::validate

    fn Policy::validate(self : Policy) -> Array[Diagnostic]

    Checks structural invariants before evaluation or planning.

    Policy::verify_repair

    fn Policy::verify_repair(self : Policy, repair : Repair) -> RepairVerification

    Verify a repair received from storage or another process before applying it.

    Probe

    pub(all) struct Probe {
    feature : String
    from : Value
    to : Value
    cost : Int
    before : Truth
    after : Truth
    flips : Bool
    } derive(Eq,
    Debug
    )

    Result of changing exactly one feature. Probes expose local sensitivity even when no single edit is sufficient to flip the complete policy.

    Probe::render

    fn Probe::render(self : Probe) -> String

    Repair

    pub(all) struct Repair {
    changes : Array[Change]
    cost : Int
    result : Truth
    trace : Trace
    } derive(Eq,
    Debug
    )

    Repair::apply

    fn Repair::apply(self : Repair, environment : Array[Binding]) -> Array[Binding]

    Repair::summary

    fn Repair::summary(self : Repair) -> String

    RepairFeatureUsage

    pub(all) struct RepairFeatureUsage {
    feature : String
    uses : Int
    first_rank : Int
    total_cost : Int
    values : Array[Value]
    common_to_all : Bool
    single_target_value : Bool
    } derive(Eq,
    Debug
    )

    RepairFeatureUsage::average_cost

    fn RepairFeatureUsage::average_cost(self : RepairFeatureUsage) -> Int

    RepairFeatureUsage::values_text

    fn RepairFeatureUsage::values_text(self : RepairFeatureUsage) -> String

    RepairPortfolio

    pub(all) struct RepairPortfolio {
    policy_name : String
    baseline : Truth
    target : Truth
    repair_count : Int
    cheapest_cost : Int
    most_expensive_cost : Int
    total_changes : Int
    average_changes : Int
    consensus_features : Array[String]
    optional_features : Array[String]
    usages : Array[RepairFeatureUsage]
    } derive(Eq,
    Debug
    )

    RepairPortfolio::feature_usage

    fn RepairPortfolio::feature_usage(self : RepairPortfolio, feature : String) -> RepairFeatureUsage?

    RepairPortfolio::has_consensus

    fn RepairPortfolio::has_consensus(self : RepairPortfolio) -> Bool

    RepairPortfolio::to_json

    fn RepairPortfolio::to_json(self : RepairPortfolio) -> String

    RepairPortfolio::to_markdown

    fn RepairPortfolio::to_markdown(self : RepairPortfolio) -> String

    RepairVerification

    pub(all) struct RepairVerification {
    valid : Bool
    diagnostics : Array[Diagnostic]
    outcome : Truth
    computed_cost : Int
    } derive(Eq,
    Debug
    )

    Scenario

    pub(all) struct Scenario {
    name : String
    environment : Array[Binding]
    } derive(Eq,
    Debug
    )

    ScenarioResult

    pub(all) struct ScenarioResult {
    name : String
    truth : Truth
    trace : Trace
    changed_from_baseline : Bool
    } derive(Eq,
    Debug
    )

    Span

    pub(all) struct Span {
    offset : Int
    line : Int
    column : Int
    } derive(Eq,
    Debug
    )

    A source location used by parser and validation diagnostics.

    Trace

    pub(all) struct Trace {
    expression : String
    truth : Truth
    reason : String
    children : Array[Trace]
    } derive(Eq,
    Debug
    )

    A recursively explainable evaluation node.

    Trace::blocking_leaves

    fn Trace::blocking_leaves(self : Trace) -> Array[Trace]

    Leaf-level causes that currently prevent a trace from being true. This is intentionally structural: callers receive the exact evaluated predicates, not a second heuristic explanation of the policy.

    Trace::to_mermaid

    fn Trace::to_mermaid(self : Trace) -> String

    Trace::to_text

    fn Trace::to_text(self : Trace) -> String

    A compact multi-line explanation suited to terminals and log files.

    Truth

    pub(all) enum Truth {
    Yes
    No
    Unknown
    } derive(Eq,
    Debug
    )

    Kleene three-valued truth. Unknown is deliberately preserved: a missing input must not silently become false in policy evaluation.

    Truth::conjunction

    fn Truth::conjunction(self : Truth, other : Truth) -> Truth

    Truth::disjunction

    fn Truth::disjunction(self : Truth, other : Truth) -> Truth

    Truth::not

    fn Truth::not(self : Truth) -> Truth

    Truth::render

    fn Truth::render(self : Truth) -> String

    Value

    pub(all) enum Value {
    Integer(Int)
    Boolean(Bool)
    Text(String)
    } derive(Eq,
    Debug
    )

    Scalar values accepted by the FlipSpec DSL.

    Value::kind

    fn Value::kind(self : Value) -> String

    Value::plain

    fn Value::plain(self : Value) -> String

    Value::render

    fn Value::render(self : Value) -> String

    diff_environments

    fn diff_environments(before : Array[Binding], after : Array[Binding]) -> Array[EnvironmentChange]

    Deterministic environment diff used when explaining scenario regressions.

    environment_get

    fn environment_get(environment : Array[Binding], name : String) -> Value?

    environment_set

    fn environment_set(environment : Array[Binding], name : String, value : Value) -> Array[Binding]

    evaluate

    fn evaluate(expression : Expr, environment : Array[Binding]) -> Evaluation

    feature

    fn feature(name : String, current : Value, domain : Array[Value], cost? : Int, locked? : Bool) -> Feature

    parse

    fn parse(source : String) -> Result[Policy, Diagnostic]

    Parse a complete FlipSpec document.

    plan_options

    fn plan_options(max_results? : Int, max_evaluations? : Int) -> PlanOptions

    policy

    fn policy(name : String, features : Array[Feature], goal : Expr) -> Policy

    scenario

    fn scenario(name : String, environment : Array[Binding]) -> Scenario