{"size": 2650, "ext": "scrbl", "max_stars_repo_path": "examples/boolean.scrbl", "max_stars_repo_name": "khinsen/leibniz-examples", "max_stars_repo_stars_event_min_datetime": "2017-03-22T08:37:51.000Z", "max_stars_repo_stars_event_max_datetime": "2020-10-12T22:58:00.000Z", "max_issues_repo_path": "examples/boolean.scrbl", "max_issues_repo_name": "khinsen/leibniz-examples", "max_issues_repo_issues_event_min_datetime": null, "max_issues_repo_issues_event_max_datetime": null, "max_forks_repo_path": "examples/boolean.scrbl", "max_forks_repo_name": "khinsen/leibniz-examples", "max_forks_repo_forks_event_min_datetime": "2018-02-05T07:35:03.000Z", "max_forks_repo_forks_event_max_datetime": "2020-10-12T22:58:02.000Z"}
{"max_stars_count": 2, "max_issues_count": null, "max_forks_count": 3, "avg_line_length": 31.1764705882, "max_line_length": 84, "alphanum_fraction": 0.6335849057}
#lang leibniz

@title{Boolean algebra}
@author{Konrad Hinsen}

@context["boolean" #:use "builtins/truth"]{
@section{Logical operations}

The following operators are defined on terms of sort @sort{boolean}:

@tabular[#:sep @hspace[1]
         @list[ @list["NOT:"  @op{¬(boolean) : boolean}]
                @list["AND:"  @op{boolean ∧ boolean : boolean}]
                @list["OR:"   @op{boolean ∨ boolean : boolean}]
                @list["XOR:"  @op{boolean ⊻ boolean : boolean}] ]]

@subsection{Rewrite rules}

@subsubsection{Eliminate NOT and OR}

NOT is replaced by XOR with @term{true}:
  @inset{@rule{¬(X) ⇒ true ⊻ X ∀ X:boolean}}

OR is replaced by XOR and AND:
  @inset{@rule{X ∨ Y ⇒ X ⊻ Y ⊻ (X ∧ Y) ∀ X:boolean  ∀ Y:boolean}}

@subsubsection{Simplify AND relations}

AND is @term{false} if one of its arguments is @term{false}:
  @inset{@rule{X ∧ false ⇒ false ∀ X:boolean}
         @rule{false ∧ X ⇒ false ∀ X:boolean}}

If one argument of AND is @term{true}, the result is the other argument:
  @inset{@rule{X ∧ true ⇒ X ∀ X:boolean}
         @rule{true ∧ X ⇒ X ∀ X:boolean}}

If the two arguments to AND are equal, they are also equal to the result:
  @inset{@rule{X ∧ X ⇒ X ∀ X:boolean}}

@subsubsection{Simplify XOR relations}

XOR with @term{false} leaves truth values unchanged:
  @inset{@rule{X ⊻ false ⇒ X ∀ X:boolean}
         @rule{false ⊻ X ⇒ X ∀ X:boolean}}

If the two arguments to XOR are equal, the result is @term{false}:
  @inset{@rule{X ⊻ X ⇒ false ∀ X:boolean}}

@subsubsection{Standardize combinations of XOR and AND}

The above rules will reduce any boolean expression to a combination of XOR and AND
operations that allow no further simplification. However, it is still possible that
logically equal expressions are rewritten into distinct syntactical forms, making it
difficult to verify that they are equal. The following rule standardizes results
by replacing XOR inside AND by AND inside XOR:
  @inset{@rule{X ∧ (Y ⊻ Z) ⇒ (X ∧ Y) ⊻ (X ∧ Z)
               ∀ X:boolean  ∀ Y:boolean   ∀ Z:boolean}}


@subsection{Tests}

Truth table for Not:
  @inset{@test{¬(false) ⇒ true}
         @test{¬(true) ⇒ false}}

Truth table for AND:
  @inset{@test{false ∧ false ⇒ false}
         @test{false ∧ true ⇒ false}
         @test{true ∧ false ⇒ false}
         @test{true ∧ true ⇒ true}}

Truth table for OR:
  @inset{@test{false ∨ false ⇒ false}
         @test{false ∨ true ⇒ true}
         @test{true ∨ false ⇒ true}
         @test{true ∨ true ⇒ true}}

Truth table for XOR:
  @inset{@test{false ⊻ false ⇒ false}
         @test{false ⊻ true ⇒ true}
         @test{true ⊻ false ⇒ true}
         @test{true ⊻ true ⇒ false}}

}
