File: Mathlib/Tactic/Polyrith.lean

full_name: Mathlib.Tactic.Polyrith.initFn._@.Mathlib.Tactic.Polyrith._hyg.7
code: initialize registerTraceClass `Meta.Tactic.polyrith
goal: IO Unit

full_name: Mathlib.Tactic.Polyrith.Poly.neg
code: /--
A datatype representing the semantics of multivariable polynomials.
Each `Poly` can be converted into a string.
-/
inductive Poly
  | const : ℚ → Poly
  | var : ℕ → Poly
  | hyp : Term → Poly
  | add : Poly → Poly → Poly
  | sub : Poly → Poly → Poly
  | mul : Poly → Poly → Poly
  | div : Poly → Poly → Poly
  | pow : Poly → Poly → Poly
  | neg : Poly → Poly
  deriving BEq, Repr
goal: Mathlib.Tactic.Polyrith.Poly → Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.instReprPoly
code: /--
A datatype representing the semantics of multivariable polynomials.
Each `Poly` can be converted into a string.
-/
inductive Poly
  | const : ℚ → Poly
  | var : ℕ → Poly
  | hyp : Term → Poly
  | add : Poly → Poly → Poly
  | sub : Poly → Poly → Poly
  | mul : Poly → Poly → Poly
  | div : Poly → Poly → Poly
  | pow : Poly → Poly → Poly
  | neg : Poly → Poly
  deriving BEq, Repr
goal: Repr Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.Poly.const
code: /--
A datatype representing the semantics of multivariable polynomials.
Each `Poly` can be converted into a string.
-/
inductive Poly
  | const : ℚ → Poly
  | var : ℕ → Poly
  | hyp : Term → Poly
  | add : Poly → Poly → Poly
  | sub : Poly → Poly → Poly
  | mul : Poly → Poly → Poly
  | div : Poly → Poly → Poly
  | pow : Poly → Poly → Poly
  | neg : Poly → Poly
  deriving BEq, Repr
goal: ℚ → Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.Poly
code: /--
A datatype representing the semantics of multivariable polynomials.
Each `Poly` can be converted into a string.
-/
inductive Poly
  | const : ℚ → Poly
  | var : ℕ → Poly
  | hyp : Term → Poly
  | add : Poly → Poly → Poly
  | sub : Poly → Poly → Poly
  | mul : Poly → Poly → Poly
  | div : Poly → Poly → Poly
  | pow : Poly → Poly → Poly
  | neg : Poly → Poly
  deriving BEq, Repr
goal: Type

full_name: Mathlib.Tactic.Polyrith.Poly.hyp
code: /--
A datatype representing the semantics of multivariable polynomials.
Each `Poly` can be converted into a string.
-/
inductive Poly
  | const : ℚ → Poly
  | var : ℕ → Poly
  | hyp : Term → Poly
  | add : Poly → Poly → Poly
  | sub : Poly → Poly → Poly
  | mul : Poly → Poly → Poly
  | div : Poly → Poly → Poly
  | pow : Poly → Poly → Poly
  | neg : Poly → Poly
  deriving BEq, Repr
goal: Lean.Term → Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.Poly.add
code: /--
A datatype representing the semantics of multivariable polynomials.
Each `Poly` can be converted into a string.
-/
inductive Poly
  | const : ℚ → Poly
  | var : ℕ → Poly
  | hyp : Term → Poly
  | add : Poly → Poly → Poly
  | sub : Poly → Poly → Poly
  | mul : Poly → Poly → Poly
  | div : Poly → Poly → Poly
  | pow : Poly → Poly → Poly
  | neg : Poly → Poly
  deriving BEq, Repr
goal: Mathlib.Tactic.Polyrith.Poly → Mathlib.Tactic.Polyrith.Poly → Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.Poly.div
code: /--
A datatype representing the semantics of multivariable polynomials.
Each `Poly` can be converted into a string.
-/
inductive Poly
  | const : ℚ → Poly
  | var : ℕ → Poly
  | hyp : Term → Poly
  | add : Poly → Poly → Poly
  | sub : Poly → Poly → Poly
  | mul : Poly → Poly → Poly
  | div : Poly → Poly → Poly
  | pow : Poly → Poly → Poly
  | neg : Poly → Poly
  deriving BEq, Repr
goal: Mathlib.Tactic.Polyrith.Poly → Mathlib.Tactic.Polyrith.Poly → Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.Poly.pow
code: /--
A datatype representing the semantics of multivariable polynomials.
Each `Poly` can be converted into a string.
-/
inductive Poly
  | const : ℚ → Poly
  | var : ℕ → Poly
  | hyp : Term → Poly
  | add : Poly → Poly → Poly
  | sub : Poly → Poly → Poly
  | mul : Poly → Poly → Poly
  | div : Poly → Poly → Poly
  | pow : Poly → Poly → Poly
  | neg : Poly → Poly
  deriving BEq, Repr
goal: Mathlib.Tactic.Polyrith.Poly → Mathlib.Tactic.Polyrith.Poly → Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.instBEqPoly
code: /--
A datatype representing the semantics of multivariable polynomials.
Each `Poly` can be converted into a string.
-/
inductive Poly
  | const : ℚ → Poly
  | var : ℕ → Poly
  | hyp : Term → Poly
  | add : Poly → Poly → Poly
  | sub : Poly → Poly → Poly
  | mul : Poly → Poly → Poly
  | div : Poly → Poly → Poly
  | pow : Poly → Poly → Poly
  | neg : Poly → Poly
  deriving BEq, Repr
goal: BEq Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.Poly.var
code: /--
A datatype representing the semantics of multivariable polynomials.
Each `Poly` can be converted into a string.
-/
inductive Poly
  | const : ℚ → Poly
  | var : ℕ → Poly
  | hyp : Term → Poly
  | add : Poly → Poly → Poly
  | sub : Poly → Poly → Poly
  | mul : Poly → Poly → Poly
  | div : Poly → Poly → Poly
  | pow : Poly → Poly → Poly
  | neg : Poly → Poly
  deriving BEq, Repr
goal: ℕ → Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.Poly.mul
code: /--
A datatype representing the semantics of multivariable polynomials.
Each `Poly` can be converted into a string.
-/
inductive Poly
  | const : ℚ → Poly
  | var : ℕ → Poly
  | hyp : Term → Poly
  | add : Poly → Poly → Poly
  | sub : Poly → Poly → Poly
  | mul : Poly → Poly → Poly
  | div : Poly → Poly → Poly
  | pow : Poly → Poly → Poly
  | neg : Poly → Poly
  deriving BEq, Repr
goal: Mathlib.Tactic.Polyrith.Poly → Mathlib.Tactic.Polyrith.Poly → Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.Poly.sub
code: /--
A datatype representing the semantics of multivariable polynomials.
Each `Poly` can be converted into a string.
-/
inductive Poly
  | const : ℚ → Poly
  | var : ℕ → Poly
  | hyp : Term → Poly
  | add : Poly → Poly → Poly
  | sub : Poly → Poly → Poly
  | mul : Poly → Poly → Poly
  | div : Poly → Poly → Poly
  | pow : Poly → Poly → Poly
  | neg : Poly → Poly
  deriving BEq, Repr
goal: Mathlib.Tactic.Polyrith.Poly → Mathlib.Tactic.Polyrith.Poly → Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.Poly.format
code: /--
This converts a poly object into a string representing it. The string
maintains the semantic structure of the poly object.

The output of this function must be valid Python syntax, and it assumes the variables `varN` from
`scripts/polyrith.py.`
-/
def Poly.format : Poly → Lean.Format
  
goal: Mathlib.Tactic.Polyrith.Poly → Lean.Format

full_name: Mathlib.Tactic.Polyrith.instToFormatPoly
code: instance : Lean.ToFormat Poly 
goal: Lean.ToFormat Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.instToStringPoly
code: instance : ToString Poly 
goal: ToString Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.instReprPoly_1
code: instance : Repr Poly 
goal: Repr Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.instInhabitedPoly
code: instance : Inhabited Poly 
goal: Inhabited Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.instQuoteIntMkStr1_mathlib
code: instance : Quote ℤ 
goal: Lean.Quote ℤ

full_name: Mathlib.Tactic.Polyrith.instQuoteRatMkStr1_mathlib
code: instance : Quote ℚ 
goal: Lean.Quote ℚ

full_name: Mathlib.Tactic.Polyrith.Poly.toSyntax
code: /-- Converts a `Poly` expression into a `Syntax` suitable as an input to `linear_combination`. -/
def Poly.toSyntax : Poly → Unhygienic Syntax.Term
  
goal: Mathlib.Tactic.Polyrith.Poly → Lean.Unhygienic Lean.Term

full_name: Mathlib.Tactic.Polyrith.parse
code: /-- Reifies a ring expression of type `α` as a `Poly`. -/
partial def parse {u : Level} {α : Q(Type u)} (sα : Q(CommSemiring $α))
    (c : Ring.Cache sα) (e : Q($α)) : AtomM Poly 
goal: Mathlib.Tactic.AtomM Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.Source.fvar
code: /-- The possible hypothesis sources for a polyrith proof. -/
inductive Source where
  /-- `input n` refers to the `n`'th input `ai` in `polyrith [a1, ..., an]`. -/
  | input : Nat → Source
  /-- `fvar h` refers to hypothesis `h` from the local context. -/
  | fvar : FVarId → Source
goal: Lean.FVarId → Mathlib.Tactic.Polyrith.Source

full_name: Mathlib.Tactic.Polyrith.Source.input
code: /-- The possible hypothesis sources for a polyrith proof. -/
inductive Source where
  /-- `input n` refers to the `n`'th input `ai` in `polyrith [a1, ..., an]`. -/
  | input : Nat → Source
  /-- `fvar h` refers to hypothesis `h` from the local context. -/
  | fvar : FVarId → Source
goal: ℕ → Mathlib.Tactic.Polyrith.Source

full_name: Mathlib.Tactic.Polyrith.Source
code: /-- The possible hypothesis sources for a polyrith proof. -/
inductive Source where
  /-- `input n` refers to the `n`'th input `ai` in `polyrith [a1, ..., an]`. -/
  | input : Nat → Source
  /-- `fvar h` refers to hypothesis `h` from the local context. -/
  | fvar : FVarId → Source
goal: Type

full_name: Mathlib.Tactic.Polyrith.parseContext
code: /-- The first half of `polyrith` produces a list of arguments to be sent to Sage. -/
def parseContext (only : Bool) (hyps : Array Expr) (tgt : Expr) :
    AtomM (Expr × Array (Source × Poly) × Poly) 
goal: Mathlib.Tactic.AtomM
  (Lean.Expr × Array (Mathlib.Tactic.Polyrith.Source × Mathlib.Tactic.Polyrith.Poly) × Mathlib.Tactic.Polyrith.Poly)

full_name: Mathlib.Tactic.Polyrith.parseContext.processHyp
code: /-- The first half of `polyrith` produces a list of arguments to be sent to Sage. -/
def parseContext (only : Bool) (hyps : Array Expr) (tgt : Expr) :
    AtomM (Expr × Array (Source × Poly) × Poly) 
goal: Mathlib.Tactic.AtomM (Array (Mathlib.Tactic.Polyrith.Source × Mathlib.Tactic.Polyrith.Poly))

full_name: Mathlib.Tactic.Polyrith.createSageArgs
code: /-- Constructs the list of arguments to pass to the external sage script `polyrith_sage.py`. -/
def createSageArgs (trace : Bool) (α : Expr) (atoms : Nat)
    (hyps : Array (Source × Poly)) (tgt : Poly) : Array String 
goal: Array String

full_name: Mathlib.Tactic.Polyrith.instFromJsonRat_mathlib
code: /-- A JSON parser for `ℚ` specific to the return value of `polyrith_sage.py`. -/
local instance : FromJson ℚ 
goal: Lean.FromJson ℚ

full_name: Mathlib.Tactic.Polyrith.Poly.unNeg?
code: /-- Removes an initial `-` sign from a polynomial with negative leading coefficient. -/
def Poly.unNeg? : Poly → Option Poly
  
goal: Mathlib.Tactic.Polyrith.Poly → Option Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.Poly.add'
code: /-- Adds two polynomials, performing some simple simplifications for presentation like
`a + -b = a - b`. -/
def Poly.add' : Poly → Poly → Poly
  
goal: Mathlib.Tactic.Polyrith.Poly → Mathlib.Tactic.Polyrith.Poly → Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.Poly.mul'
code: /-- Multiplies two polynomials, performing some simple simplifications for presentation like
`1 * a = a`. -/
def Poly.mul' : Poly → Poly → Poly
  
goal: Mathlib.Tactic.Polyrith.Poly → Mathlib.Tactic.Polyrith.Poly → Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.Poly.unDiv?
code: /-- Extracts the divisor `c : ℕ` from a polynomial of the form `1/c * b`. -/
def Poly.unDiv? : Poly → Option (Poly × ℕ)
  
goal: Mathlib.Tactic.Polyrith.Poly → Option (Mathlib.Tactic.Polyrith.Poly × ℕ)

full_name: Mathlib.Tactic.Polyrith.Poly.pow'
code: /-- Constructs a power expression `v_i ^ j`, performing some simplifications in trivial cases. -/
def Poly.pow' : ℕ → ℕ → Poly
  
goal: ℕ → ℕ → Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.Poly.sumM
code: /-- Constructs a sum from a monadic function supplying the monomials. -/
def Poly.sumM {m : Type → Type*} {α : Type*} [Monad m] (a : Array α) (f : α → m Poly) : m Poly 
goal: m Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.instFromJsonPoly
code: instance : FromJson Poly 
goal: Lean.FromJson Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.SageCoeffAndPower
code: /-- A schema for the data reported by the Sage calculation -/
structure SageCoeffAndPower where
  /-- The function call produces an array of polynomials
  parallel to the input list of hypotheses. -/
  coeffs : Array Poly
  /-- Sage produces an exponent (default 1) in the case where the hypothesess
  sum to a power of the goal. -/
  power  : ℕ
  deriving FromJson, Repr
goal: Type

full_name: Mathlib.Tactic.Polyrith.SageCoeffAndPower.power
code: /-- A schema for the data reported by the Sage calculation -/
structure SageCoeffAndPower where
  /-- The function call produces an array of polynomials
  parallel to the input list of hypotheses. -/
  coeffs : Array Poly
  /-- Sage produces an exponent (default 1) in the case where the hypothesess
  sum to a power of the goal. -/
  power  : ℕ
  deriving FromJson, Repr
goal: ℕ

full_name: Mathlib.Tactic.Polyrith.SageCoeffAndPower.coeffs
code: /-- A schema for the data reported by the Sage calculation -/
structure SageCoeffAndPower where
  /-- The function call produces an array of polynomials
  parallel to the input list of hypotheses. -/
  coeffs : Array Poly
  /-- Sage produces an exponent (default 1) in the case where the hypothesess
  sum to a power of the goal. -/
  power  : ℕ
  deriving FromJson, Repr
goal: Array Mathlib.Tactic.Polyrith.Poly

full_name: Mathlib.Tactic.Polyrith.instReprSageCoeffAndPower
code: /-- A schema for the data reported by the Sage calculation -/
structure SageCoeffAndPower where
  /-- The function call produces an array of polynomials
  parallel to the input list of hypotheses. -/
  coeffs : Array Poly
  /-- Sage produces an exponent (default 1) in the case where the hypothesess
  sum to a power of the goal. -/
  power  : ℕ
  deriving FromJson, Repr
goal: Repr Mathlib.Tactic.Polyrith.SageCoeffAndPower

full_name: Mathlib.Tactic.Polyrith.instFromJsonSageCoeffAndPower
code: FromJson
goal: Lean.FromJson Mathlib.Tactic.Polyrith.SageCoeffAndPower

full_name: Mathlib.Tactic.Polyrith.SageSuccess.data
code: /-- The result of a sage call in the success case. -/
structure SageSuccess where
  /-- The script returns a string containing python script to be sent to the remote server,
  when the tracing option is set. -/
  trace : Option String := none
  /-- The main result of the function call is an array of polynomials
  parallel to the input list of hypotheses and an exponent for the goal. -/
  data : Option SageCoeffAndPower := none
  deriving FromJson, Repr
goal: Option Mathlib.Tactic.Polyrith.SageCoeffAndPower

full_name: Mathlib.Tactic.Polyrith.SageSuccess.trace
code: /-- The result of a sage call in the success case. -/
structure SageSuccess where
  /-- The script returns a string containing python script to be sent to the remote server,
  when the tracing option is set. -/
  trace : Option String := none
  /-- The main result of the function call is an array of polynomials
  parallel to the input list of hypotheses and an exponent for the goal. -/
  data : Option SageCoeffAndPower := none
  deriving FromJson, Repr
goal: Option String

full_name: Mathlib.Tactic.Polyrith.SageSuccess
code: /-- The result of a sage call in the success case. -/
structure SageSuccess where
  /-- The script returns a string containing python script to be sent to the remote server,
  when the tracing option is set. -/
  trace : Option String := none
  /-- The main result of the function call is an array of polynomials
  parallel to the input list of hypotheses and an exponent for the goal. -/
  data : Option SageCoeffAndPower := none
  deriving FromJson, Repr
goal: Type

full_name: Mathlib.Tactic.Polyrith.instReprSageSuccess
code: /-- The result of a sage call in the success case. -/
structure SageSuccess where
  /-- The script returns a string containing python script to be sent to the remote server,
  when the tracing option is set. -/
  trace : Option String := none
  /-- The main result of the function call is an array of polynomials
  parallel to the input list of hypotheses and an exponent for the goal. -/
  data : Option SageCoeffAndPower := none
  deriving FromJson, Repr
goal: Repr Mathlib.Tactic.Polyrith.SageSuccess

full_name: Mathlib.Tactic.Polyrith.instFromJsonSageSuccess
code: FromJson
goal: Lean.FromJson Mathlib.Tactic.Polyrith.SageSuccess

full_name: Mathlib.Tactic.Polyrith.SageError
code: /-- The result of a sage call in the failure case. -/
structure SageError where
  /-- The error kind -/
  name : String
  /-- The error message -/
  value : String
  deriving FromJson
goal: Type

full_name: Mathlib.Tactic.Polyrith.SageError.name
code: /-- The result of a sage call in the failure case. -/
structure SageError where
  /-- The error kind -/
  name : String
  /-- The error message -/
  value : String
  deriving FromJson
goal: String

full_name: Mathlib.Tactic.Polyrith.SageError.value
code: /-- The result of a sage call in the failure case. -/
structure SageError where
  /-- The error kind -/
  name : String
  /-- The error message -/
  value : String
  deriving FromJson
goal: String

full_name: Mathlib.Tactic.Polyrith.instFromJsonSageError
code: FromJson
goal: Lean.FromJson Mathlib.Tactic.Polyrith.SageError

full_name: Mathlib.Tactic.Polyrith.SageResult
code: /-- The result of a sage call. -/
def SageResult 
goal: Type

full_name: Mathlib.Tactic.Polyrith.instFromJsonSageResult
code: instance : FromJson SageResult 
goal: Lean.FromJson Mathlib.Tactic.Polyrith.SageResult

full_name: Mathlib.Tactic.Polyrith.sageOutput
code: /--
This tactic calls python from the command line with the args in `arg_list`.
The output printed to the console is parsed as a `Json`.
It assumes that `python3` is available on the path.
-/
def sageOutput (args : Array String) : IO SageResult 
goal: IO Mathlib.Tactic.Polyrith.SageResult

full_name: Mathlib.Tactic.Polyrith.polyrith
code: /--
This is the main body of the `polyrith` tactic. It takes in the following inputs:
* `only : Bool` - This represents whether the user used the key word "only"
* `hyps : Array Expr` - the hypotheses/proof terms selected by the user
* `traceOnly : Bool` - If enabled, the returned syntax will be `.missing`

First, the tactic converts the target into a `Poly`, and finds out what type it
is an equality of. (It also fills up a list of `Expr`s with its atoms). Then, it
collects all the relevant hypotheses/proof terms from the context, and from those
selected by the user, taking into account whether `only` is true. (The list of atoms is
updated accordingly as well).

This information is used to create a list of args that get used in a call to
the appropriate python file that executes a grobner basis computation. The
output of this computation is a `String` representing the certificate. This
string is parsed into a list of `Poly` objects that are then converted into
`Expr`s (using the updated list of atoms).

the names of the hypotheses, along with the corresponding coefficients are
given to `linear_combination`. If that tactic succeeds, the user is prompted
to replace the call to `polyrith` with the appropriate call to
`linear_combination`.

Returns `.error g` if this was a "dry run" attempt that does not actually invoke sage.
-/
def polyrith (g : MVarId) (only : Bool) (hyps : Array Expr)
    (traceOnly := false) : MetaM (Except MVarId (TSyntax `tactic)) 
goal: Lean.MetaM (Except Lean.MVarId (Lean.TSyntax `tactic))

full_name: Mathlib.Tactic.Polyrith.polyrith.byRing
code: /--
This is the main body of the `polyrith` tactic. It takes in the following inputs:
* `only : Bool` - This represents whether the user used the key word "only"
* `hyps : Array Expr` - the hypotheses/proof terms selected by the user
* `traceOnly : Bool` - If enabled, the returned syntax will be `.missing`

First, the tactic converts the target into a `Poly`, and finds out what type it
is an equality of. (It also fills up a list of `Expr`s with its atoms). Then, it
collects all the relevant hypotheses/proof terms from the context, and from those
selected by the user, taking into account whether `only` is true. (The list of atoms is
updated accordingly as well).

This information is used to create a list of args that get used in a call to
the appropriate python file that executes a grobner basis computation. The
output of this computation is a `String` representing the certificate. This
string is parsed into a list of `Poly` objects that are then converted into
`Expr`s (using the updated list of atoms).

the names of the hypotheses, along with the corresponding coefficients are
given to `linear_combination`. If that tactic succeeds, the user is prompted
to replace the call to `polyrith` with the appropriate call to
`linear_combination`.

Returns `.error g` if this was a "dry run" attempt that does not actually invoke sage.
-/
def polyrith (g : MVarId) (only : Bool) (hyps : Array Expr)
    (traceOnly := false) : MetaM (Except MVarId (TSyntax `tactic)) 
goal: Mathlib.Tactic.AtomM (Except Lean.MVarId (Lean.TSyntax `tactic))

full_name: Mathlib.Tactic.Polyrith.«tacticPolyrithOnly[_]»
code: /--
Attempts to prove polynomial equality goals through polynomial arithmetic
on the hypotheses (and additional proof terms if the user specifies them).
It proves the goal by generating an appropriate call to the tactic
`linear_combination`. If this call succeeds, the call to `linear_combination`
is suggested to the user.

* `polyrith` will use all relevant hypotheses in the local context.
* `polyrith [t1, t2, t3]` will add proof terms t1, t2, t3 to the local context.
* `polyrith only [h1, h2, h3, t1, t2, t3]` will use only local hypotheses
  `h1`, `h2`, `h3`, and proofs `t1`, `t2`, `t3`. It will ignore the rest of the local context.

Notes:
* This tactic only works with a working internet connection, since it calls Sage
  using the SageCell web API at <https://sagecell.sagemath.org/>.
  Many thanks to the Sage team and organization for allowing this use.
* This tactic assumes that the user has `python3` installed and available on the path.
  (Test by opening a terminal and executing `python3 --version`.)
  It also assumes that the `requests` library is installed: `python3 -m pip install requests`.

Examples:

```lean
example (x y : ℚ) (h1 : x*y + 2*x = 1) (h2 : x = y) :
    x*y = -2*y + 1 := by
  polyrith
-- Try this: linear_combination h1 - 2 * h2

example (x y z w : ℚ) (hzw : z = w) : x*z + 2*y*z = x*w + 2*y*w := by
  polyrith
-- Try this: linear_combination (2 * y + x) * hzw

constant scary : ∀ a b : ℚ, a + b = 0

example (a b c d : ℚ) (h : a + b = 0) (h2: b + c = 0) : a + b + c + d = 0 := by
  polyrith only [scary c d, h]
-- Try this: linear_combination scary c d + h
```
-/
syntax "polyrith" (&" only")? (" [" term,* "]")? : tactic
goal: Lean.ParserDescr

full_name: Mathlib.Tactic.Polyrith.«_aux_Mathlib_Tactic_Polyrith___elabRules_Mathlib_Tactic_Polyrith_tacticPolyrithOnly[_]_1»
code: elab_rules : tactic
  | `(tactic| polyrith%$tk $[only%$onlyTk]? $[[$hyps,*]]?) => do
    let hyps ← hyps.map (·.getElems) |>.getD #[] |>.mapM (elabTerm · none)
    let traceMe ← Lean.isTracingEnabledFor `Meta.Tactic.polyrith
    match ← polyrith (← getMainGoal) onlyTk.isSome hyps traceMe with
    | .ok stx =>
      replaceMainGoal []
      if !traceMe then Lean.Meta.Tactic.TryThis.addSuggestion tk stx
    | .error g => replaceMainGoal [g]
goal: Lean.Elab.Tactic.Tactic