# Theory Syntax

```section ‹Syntax›

theory Syntax imports List_Syntax begin

subsection ‹Terms and Formulas›

datatype tm
= Var nat (‹❙#›)
| Fun nat ‹tm list› (‹❙†›)

datatype fm
= Falsity (‹❙⊥›)
| Pre nat ‹tm list› (‹❙‡›)
| Imp fm fm (infixr ‹❙⟶› 55)
| Uni fm (‹❙∀›)

type_synonym sequent = ‹fm list × fm list›

subsubsection ‹Substitution›

primrec add_env :: ‹'a ⇒ (nat ⇒ 'a) ⇒ nat ⇒ 'a› (infix ‹⨟› 0) where
‹(t ⨟ s) 0 = t›
| ‹(t ⨟ s) (Suc n) = s n›

primrec lift_tm :: ‹tm ⇒ tm› where
‹lift_tm (❙#n) = ❙#(n+1)›
| ‹lift_tm (❙†f ts) = ❙†f (map lift_tm ts)›

primrec sub_tm :: ‹(nat ⇒ tm) ⇒ tm ⇒ tm› where
‹sub_tm s (❙#n) = s n›
| ‹sub_tm s (❙†f ts) = ❙†f (map (sub_tm s) ts)›

primrec sub_fm :: ‹(nat ⇒ tm) ⇒ fm ⇒ fm› where
‹sub_fm _ ❙⊥ = ❙⊥›
| ‹sub_fm s (❙‡P ts) = ❙‡P (map (sub_tm s) ts)›
| ‹sub_fm s (p ❙⟶ q) = sub_fm s p ❙⟶ sub_fm s q›
| ‹sub_fm s (❙∀p) = ❙∀(sub_fm (❙#0 ⨟ λn. lift_tm (s n)) p)›

abbreviation inst_single :: ‹tm ⇒ fm ⇒ fm› (‹⟨_⟩›) where
‹⟨t⟩ ≡ sub_fm (t ⨟ ❙#)›

subsubsection ‹Variables›

primrec vars_tm :: ‹tm ⇒ nat list› where
‹vars_tm (❙#n) = [n]›
| ‹vars_tm (❙†_ ts) = concat (map vars_tm ts)›

primrec vars_fm :: ‹fm ⇒ nat list› where
‹vars_fm ❙⊥ = []›
| ‹vars_fm (❙‡_ ts) = concat (map vars_tm ts)›
| ‹vars_fm (p ❙⟶ q) = vars_fm p @ vars_fm q›
| ‹vars_fm (❙∀p) = vars_fm p›

primrec max_list :: ‹nat list ⇒ nat› where
‹max_list [] = 0›
| ‹max_list (x # xs) = max x (max_list xs)›

lemma max_list_append: ‹max_list (xs @ ys) = max (max_list xs) (max_list ys)›
by (induct xs) auto

lemma max_list_concat: ‹xs [∈] xss ⟹ max_list xs ≤ max_list (concat xss)›
by (induct xss) (auto simp: max_list_append)

lemma max_list_in: ‹max_list xs < n ⟹ n [∉] xs›
by (induct xs) auto

definition vars_fms :: ‹fm list ⇒ nat list› where
‹vars_fms A ≡ concat (map vars_fm A)›

lemma vars_fms_member: ‹p [∈] A ⟹ vars_fm p [⊆] vars_fms A›
unfolding vars_fms_def by (induct A) auto

lemma max_list_mono: ‹A [⊆] B ⟹ max_list A ≤ max_list B›
by (induct A) (simp, metis linorder_not_le list.set_intros(1) max.absorb2 max.absorb3
max_list.simps(2) max_list_in set_subset_Cons subset_code(1))

lemma max_list_vars_fms:
assumes ‹max_list (vars_fms A) ≤ n› ‹p [∈] A›
shows ‹max_list (vars_fm p) ≤ n›
using assms max_list_mono vars_fms_member by (meson dual_order.trans)

definition fresh :: ‹fm list ⇒ nat› where
‹fresh A ≡ Suc (max_list (vars_fms A))›

subsection ‹Rules›

datatype rule =
Idle | Axiom nat ‹tm list› | FlsL | FlsR | ImpL fm fm | ImpR fm fm | UniL tm fm | UniR fm

end
```