|
| 1 | +/- |
| 2 | +Copyright (c) 2026 Benjamin Brast-McKie. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Benjamin Brast-McKie |
| 5 | +-/ |
| 6 | + |
| 7 | +module |
| 8 | + |
| 9 | +public import Cslib.Logics.Propositional.Semantics.Basic |
| 10 | + |
| 11 | +/-! # Boolean Evaluation for Propositional Logic |
| 12 | +
|
| 13 | +This module defines a computable Boolean evaluation function for propositional logic, |
| 14 | +alongside the `Prop`-valued `Evaluate` from `Semantics.Basic`. |
| 15 | +
|
| 16 | +## Main Definitions |
| 17 | +
|
| 18 | +- `BoolValuation`: A Boolean propositional valuation assigns a `Bool` to each atom. |
| 19 | +- `BoolEvaluate`: Evaluate a proposition under a Boolean valuation, returning `Bool`. |
| 20 | +
|
| 21 | +## Main Results |
| 22 | +
|
| 23 | +- `BoolEvaluate_eq_iff`: Bridge lemma connecting `BoolEvaluate v φ = true` to |
| 24 | + `Evaluate (fun a => v a = true) φ`, enabling decidable evaluation. |
| 25 | +- `instDecidableBoolEvaluate`: Decidability of `Evaluate` under Boolean valuations. |
| 26 | +
|
| 27 | +## Design Notes |
| 28 | +
|
| 29 | +`BoolEvaluate` exists alongside `Evaluate` because DPLL/SAT procedures need computable |
| 30 | +`Bool` evaluation, while canonical model construction in strong completeness requires `Prop` |
| 31 | +(set membership `fun p => p ∈ S` is not decidable in general). The bridge lemma connects |
| 32 | +the two worlds: `Bool` computation to `Prop` metatheory. |
| 33 | +
|
| 34 | +## References |
| 35 | +
|
| 36 | +* [A. Chagrov, M. Zakharyaschev, *Modal Logic*][ChagrovZakharyaschev1997], Section 1.2 |
| 37 | +-/ |
| 38 | + |
| 39 | +@[expose] public section |
| 40 | + |
| 41 | +namespace Cslib.Logic.PL |
| 42 | + |
| 43 | +variable {Atom : Type*} |
| 44 | + |
| 45 | +/-- A Boolean propositional valuation assigns a `Bool` value to each atom. -/ |
| 46 | +abbrev BoolValuation (Atom : Type*) := Atom → Bool |
| 47 | + |
| 48 | +/-- Computable Boolean evaluation of a proposition; mirrors `Evaluate` with `Bool` instead of |
| 49 | +`Prop`. Use `BoolEvaluate_eq_iff` to connect results to `Evaluate`. -/ |
| 50 | +def BoolEvaluate (v : BoolValuation Atom) : PL.Proposition Atom → Bool |
| 51 | + | .atom x => v x |
| 52 | + | .bot => false |
| 53 | + | .imp a b => !BoolEvaluate v a || BoolEvaluate v b |
| 54 | + | .and a b => BoolEvaluate v a && BoolEvaluate v b |
| 55 | + | .or a b => BoolEvaluate v a || BoolEvaluate v b |
| 56 | + |
| 57 | +@[simp] theorem BoolEvaluate_atom (v : BoolValuation Atom) (x : Atom) : |
| 58 | + BoolEvaluate v (.atom x) = v x := rfl |
| 59 | + |
| 60 | +@[simp] theorem BoolEvaluate_bot (v : BoolValuation Atom) : |
| 61 | + BoolEvaluate v (.bot) = false := rfl |
| 62 | + |
| 63 | +@[simp] theorem BoolEvaluate_imp (v : BoolValuation Atom) (a b : PL.Proposition Atom) : |
| 64 | + BoolEvaluate v (.imp a b) = (!BoolEvaluate v a || BoolEvaluate v b) := rfl |
| 65 | + |
| 66 | +@[simp] theorem BoolEvaluate_and (v : BoolValuation Atom) (a b : PL.Proposition Atom) : |
| 67 | + BoolEvaluate v (.and a b) = (BoolEvaluate v a && BoolEvaluate v b) := rfl |
| 68 | + |
| 69 | +@[simp] theorem BoolEvaluate_or (v : BoolValuation Atom) (a b : PL.Proposition Atom) : |
| 70 | + BoolEvaluate v (.or a b) = (BoolEvaluate v a || BoolEvaluate v b) := rfl |
| 71 | + |
| 72 | +/-- Bridge lemma: `BoolEvaluate v φ = true` iff `Evaluate (fun a => v a = true) φ`. |
| 73 | +The `imp` case uses `cases` on `Bool` since `!a || b = true ↔ (a = true → b = true)` |
| 74 | +is not automatic from `simp`. -/ |
| 75 | +theorem BoolEvaluate_eq_iff (v : BoolValuation Atom) (φ : PL.Proposition Atom) : |
| 76 | + BoolEvaluate v φ = true ↔ Evaluate (fun a => v a = true) φ := by |
| 77 | + induction φ with |
| 78 | + | atom x => simp [BoolEvaluate, Evaluate] |
| 79 | + | bot => simp [BoolEvaluate, Evaluate] |
| 80 | + | imp a b iha ihb => |
| 81 | + simp only [BoolEvaluate, Evaluate_imp, ← iha, ← ihb] |
| 82 | + cases BoolEvaluate v a <;> cases BoolEvaluate v b <;> simp |
| 83 | + | and a b iha ihb => simp [BoolEvaluate, Evaluate, iha, ihb] |
| 84 | + | or a b iha ihb => simp [BoolEvaluate, Evaluate, iha, ihb] |
| 85 | + |
| 86 | +/-- Negation form of the bridge: `BoolEvaluate v φ = false` iff |
| 87 | +`¬ Evaluate (fun a => v a = true) φ`. -/ |
| 88 | +theorem BoolEvaluate_eq_false_iff (v : BoolValuation Atom) (φ : PL.Proposition Atom) : |
| 89 | + BoolEvaluate v φ = false ↔ ¬Evaluate (fun a => v a = true) φ := by |
| 90 | + rw [← BoolEvaluate_eq_iff] |
| 91 | + cases BoolEvaluate v φ <;> simp |
| 92 | + |
| 93 | +/-- Every propositional valuation with decidable atoms factors through `BoolEvaluate`. -/ |
| 94 | +theorem Evaluate_eq_BoolEvaluate (v : Valuation Atom) [∀ a, Decidable (v a)] |
| 95 | + (φ : PL.Proposition Atom) : |
| 96 | + Evaluate v φ ↔ BoolEvaluate (fun a => decide (v a)) φ = true := by |
| 97 | + rw [BoolEvaluate_eq_iff] |
| 98 | + induction φ with |
| 99 | + | atom x => simp [Evaluate, decide_eq_true_eq] |
| 100 | + | bot => simp [Evaluate] |
| 101 | + | imp a b iha ihb => simp [Evaluate, iha, ihb] |
| 102 | + | and a b iha ihb => simp [Evaluate, iha, ihb] |
| 103 | + | or a b iha ihb => simp [Evaluate, iha, ihb] |
| 104 | + |
| 105 | +/-- `Evaluate` under a Boolean valuation is decidable, via `BoolEvaluate_eq_iff`. -/ |
| 106 | +instance instDecidableBoolEvaluate (v : BoolValuation Atom) (φ : PL.Proposition Atom) : |
| 107 | + Decidable (Evaluate (fun a => v a = true) φ) := |
| 108 | + decidable_of_iff _ (BoolEvaluate_eq_iff v φ) |
| 109 | + |
| 110 | +end Cslib.Logic.PL |
0 commit comments