import logic namespace experiment namespace algebra inductive mul_struct [class] (A : Type) : Type := mk : (A → A → A) → mul_struct A definition mul {A : Type} [s : mul_struct A] (a b : A) := mul_struct.rec (λ f, f) s a b infixl `*` := mul end algebra open algebra namespace nat inductive nat : Type := | zero : nat | succ : nat → nat constant mul : nat → nat → nat constant add : nat → nat → nat definition mul_struct [instance] : algebra.mul_struct nat := algebra.mul_struct.mk mul end nat section open algebra nat variables a b c : nat check a * b * c definition tst1 : nat := a * b * c end section open [notations] algebra open nat -- check mul_struct nat << This is an error, we opened only the notation from algebra variables a b c : nat check a * b * c definition tst2 : nat := a * b * c end section open nat -- check mul_struct nat << This is an error, we opened only the notation from algebra variables a b c : nat check a*b*c definition tst3 : nat := #nat a*b*c end section open nat set_option pp.implicit true definition add_struct [instance] : algebra.mul_struct nat := algebra.mul_struct.mk add variables a b c : nat check #experiment.algebra a*b*c -- << is open add instead of mul definition tst4 : nat := #experiment.algebra a*b*c end end experiment