Violet

← Docs

Stack-based syntax

A definition's body can be built clause-by-clause from three tactics: \elim, \intro, and \split.

\elim

\elim names an argument already in scope and case-splits on it. Clauses must list every constructor of the eliminated type.

\let add : (m n : Nat) -> Nat \where
  add m n <= \elim m
  | add zero n => n
  | add (suc m) n => suc (add m n)

Example: sym on propositional equality

\let sym {A : 𝓤} {x y : A} : x = y -> y = x \where
  sym p <= \elim p
  | sym refl => refl

\intro

\intro pulls the next pi-bound argument from the signature into scope as a variable. Each clause then spells out the fully-applied left-hand side. This is not working well with implicit for now.

\let identity (A : 𝓤) : A -> A \where
  <= \intro
  | identity A x => x

\split

\split case-splits the topmost introduced argument. It is normally chained right after \intro.

\let neg : Bool -> Bool \where
  <= \intro
  <= \split
  | neg true => false
  | neg false => true

You can write the same function with \elim

\let neg : Bool -> Bool \where
  neg b <= \elim b
  | neg true => false
  | neg false => true

See also