File: Mathlib/Tactic/CC.lean

full_name: Mathlib.Tactic.CC.CCState.mkCore
code: /-- Make an new `CCState` from the given `config`. -/
def mkCore (config : CCConfig) : CCState 
goal: Mathlib.Tactic.CC.CCState

full_name: Mathlib.Tactic.CC.CCState.mkUsingHsCore
code: /-- Create a congruence closure state object from the given `config` using the hypotheses in the
current goal. -/
def mkUsingHsCore (config : CCConfig) : MetaM CCState 
goal: Lean.MetaM Mathlib.Tactic.CC.CCState

full_name: Mathlib.Tactic.CC.CCState.rootsCore
code: /-- Returns the root expression for each equivalence class in the graph.
If the `Bool` argument is set to `true` then it only returns roots of non-singleton classes. -/
def rootsCore (ccs : CCState) (nonsingleton : Bool) : List Expr 
goal: List Lean.Expr

full_name: Mathlib.Tactic.CC.CCState.incGMT
code: /-- Increment the Global Modification time. -/
def incGMT (ccs : CCState) : CCState 
goal: Mathlib.Tactic.CC.CCState

full_name: Mathlib.Tactic.CC.CCState.internalize
code: /-- Add the given expression to the graph. -/
def internalize (ccs : CCState) (e : Expr) : MetaM CCState 
goal: Lean.MetaM Mathlib.Tactic.CC.CCState

full_name: Mathlib.Tactic.CC.CCState.add
code: /-- Add the given proof term as a new rule.
The proof term `H` must be an `Eq _ _`, `HEq _ _`, `Iff _ _`, or a negation of these. -/
def add (ccs : CCState) (H : Expr) : MetaM CCState 
goal: Lean.MetaM Mathlib.Tactic.CC.CCState

full_name: Mathlib.Tactic.CC.CCState.isEqv
code: /-- Check whether two expressions are in the same equivalence class. -/
def isEqv (ccs : CCState) (e₁ e₂ : Expr) : MetaM Bool 
goal: Lean.MetaM Bool

full_name: Mathlib.Tactic.CC.CCState.isNotEqv
code: /-- Check whether two expressions are not in the same equivalence class. -/
def isNotEqv (ccs : CCState) (e₁ e₂ : Expr) : MetaM Bool 
goal: Lean.MetaM Bool

full_name: Mathlib.Tactic.CC.CCState.eqvProof
code: /-- Returns a proof term that the given terms are equivalent in the given `CCState` -/
def eqvProof (ccs : CCState) (e₁ e₂ : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Mathlib.Tactic.CC.CCState.proofFor
code: /-- `proofFor cc e` constructs a proof for e if it is equivalent to true in `CCState` -/
def proofFor (ccs : CCState) (e : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Mathlib.Tactic.CC.CCState.refutationFor
code: /-- `refutationFor cc e` constructs a proof for `Not e` if it is equivalent to `False` in `CCState`
-/
def refutationFor (ccs : CCState) (e : Expr) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Mathlib.Tactic.CC.CCState.proofForFalse
code: /-- If the given state is inconsistent, return a proof for `False`. Otherwise fail. -/
def proofForFalse (ccs : CCState) : MetaM Expr 
goal: Lean.MetaM Lean.Expr

full_name: Mathlib.Tactic.CC.CCState.mkUsingHs
code: /-- Create a congruence closure state object using the hypotheses in the current goal. -/
def mkUsingHs : MetaM CCState 
goal: Lean.MetaM Mathlib.Tactic.CC.CCState

full_name: Mathlib.Tactic.CC.CCState.roots
code: /-- The root expressions for each equivalence class in the graph. -/
def roots (s : CCState) : List Expr 
goal: List Lean.Expr

full_name: Mathlib.Tactic.CC.CCState.instToMessageData
code: instance : ToMessageData CCState 
goal: Lean.ToMessageData Mathlib.Tactic.CC.CCState

full_name: Mathlib.Tactic.CC.CCState.eqcOfCore
code: /-- Continue to append following expressions in the equivalence class of `e` to `r` until `f` is
found. -/
partial def eqcOfCore (s : CCState) (e : Expr) (f : Expr) (r : List Expr) : List Expr 
goal: List Lean.Expr

full_name: Mathlib.Tactic.CC.CCState.eqcOf
code: /-- The equivalence class of `e`. -/
def eqcOf (s : CCState) (e : Expr) : List Expr 
goal: List Lean.Expr

full_name: Mathlib.Tactic.CC.CCState.eqcSize
code: /-- The size of the equivalence class of `e`. -/
def eqcSize (s : CCState) (e : Expr) : Nat 
goal: ℕ

full_name: Mathlib.Tactic.CC.CCState.foldEqcCore
code: /-- Fold `f` over the equivalence class of `c`, accumulating the result in `a`.
Loops until the element `first` is encountered.

See `foldEqc` for folding `f` over all elements of the equivalence class. -/
partial def foldEqcCore {α} (s : CCState) (f : α → Expr → α) (first : Expr) (c : Expr) (a : α) :
    α 
goal: α

full_name: Mathlib.Tactic.CC.CCState.foldEqc
code: /-- Fold the function of `f` over the equivalence class of `e`. -/
def foldEqc {α} (s : CCState) (e : Expr) (a : α) (f : α → Expr → α) : α 
goal: α

full_name: Mathlib.Tactic.CC.CCState.foldEqcM
code: /-- Fold the monadic function of `f` over the equivalence class of `e`. -/
def foldEqcM {α} {m : Type → Type} [Monad m] (s : CCState) (e : Expr) (a : α)
    (f : α → Expr → m α) : m α 
goal: m α

full_name: Lean.MVarId.cc
code: /--
Applies congruence closure to solve the given metavariable.
This procedure tries to solve the goal by chaining
equalities from context and applying congruence (i.e. if `a = b`, then `f a = f b`).

The tactic works by building an equality matching graph. It's a graph where
the vertices are terms and they are linked by edges if they are known to
be equal. Once you've added all the equalities in your context, you take
the transitive closure of the graph and, for each connected component
(i.e. equivalence class) you can elect a term that will represent the
whole class and store proofs that the other elements are equal to it.
You then take the transitive closure of these equalities under the
congruence lemmas.
The `cc` implementation in Lean does a few more tricks: for example it
derives `a = b` from `Nat.succ a = Nat.succ b`, and `Nat.succ a != Nat.zero` for any `a`.
* The starting reference point is Nelson, Oppen, [Fast decision procedures based on congruence
closure](http://www.cs.colorado.edu/~bec/courses/csci5535-s09/reading/nelson-oppen-congruence.pdf),
Journal of the ACM (1980)
* The congruence lemmas for dependent type theory as used in Lean are described in
[Congruence closure in intensional type theory](https://leanprover.github.io/papers/congr.pdf)
(de Moura, Selsam IJCAR 2016).
-/
def _root_.Lean.MVarId.cc (m : MVarId) (cfg : CCConfig := {}) : MetaM Unit 
goal: Lean.MetaM Unit

full_name: Mathlib.Tactic.CC.elabCCConfig
code: /--
Allow elaboration of `CCConfig` arguments to tactics.
-/
declare_config_elab elabCCConfig CCConfig
goal: Lean.Syntax → Lean.Elab.TermElabM Mathlib.Tactic.CC.CCConfig

full_name: Mathlib.Tactic.CC.eval._@.Mathlib.Tactic.CC._hyg.1424
code: /--
Allow elaboration of `CCConfig` arguments to tactics.
-/
declare_config_elab elabCCConfig CCConfig
goal: Lean.Expr → Lean.Elab.TermElabM Mathlib.Tactic.CC.CCConfig

full_name: Mathlib.Tactic.CC.evalUnsafe._@.Mathlib.Tactic.CC._hyg.1424
code: /--
Allow elaboration of `CCConfig` arguments to tactics.
-/
declare_config_elab elabCCConfig CCConfig
goal: Lean.Expr → Lean.Elab.TermElabM Mathlib.Tactic.CC.CCConfig

full_name: Mathlib.Tactic.cc
code: /--
The congruence closure tactic `cc` tries to solve the goal by chaining
equalities from context and applying congruence (i.e. if `a = b`, then `f a = f b`).
It is a finishing tactic, i.e. it is meant to close
the current goal, not to make some inconclusive progress.
A mostly trivial example would be:

```lean
example (a b c : ℕ) (f : ℕ → ℕ) (h: a = b) (h' : b = c) : f a = f c := by
  cc
```

As an example requiring some thinking to do by hand, consider:

```lean
example (f : ℕ → ℕ) (x : ℕ)
    (H1 : f (f (f x)) = x) (H2 : f (f (f (f (f x)))) = x) :
    f x = x := by
  cc
``` -/
elab (name := _root_.Mathlib.Tactic.cc) "cc" cfg:(config)? : tactic => do
  let cfg ← elabCCConfig (mkOptionalNode cfg)
  withMainContext <| liftMetaFinishingTactic (·.cc cfg)
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.CC._aux_Mathlib_Tactic_CC___elabRules_Mathlib_Tactic_CC__root__Mathlib_Tactic_cc_1
code: /--
The congruence closure tactic `cc` tries to solve the goal by chaining
equalities from context and applying congruence (i.e. if `a = b`, then `f a = f b`).
It is a finishing tactic, i.e. it is meant to close
the current goal, not to make some inconclusive progress.
A mostly trivial example would be:

```lean
example (a b c : ℕ) (f : ℕ → ℕ) (h: a = b) (h' : b = c) : f a = f c := by
  cc
```

As an example requiring some thinking to do by hand, consider:

```lean
example (f : ℕ → ℕ) (x : ℕ)
    (H1 : f (f (f x)) = x) (H2 : f (f (f (f (f x)))) = x) :
    f x = x := by
  cc
``` -/
elab (name := _root_.Mathlib.Tactic.cc) "cc" cfg:(config)? : tactic => do
  let cfg ← elabCCConfig (mkOptionalNode cfg)
  withMainContext <| liftMetaFinishingTactic (·.cc cfg)
goal: Lean.Elab.Tactic.Tactic