|
| 1 | +import algebra.ring |
| 2 | +import tactic.chain |
| 3 | + |
| 4 | +open tactic |
| 5 | + |
| 6 | +instance is_mul_hom_of_is_monoid_hom {X Y : Type*} [monoid X] [monoid Y] |
| 7 | + (f : X → Y) [I : is_monoid_hom f] : is_mul_hom f := |
| 8 | +{..I} |
| 9 | + |
| 10 | +meta def map_one (f : expr) : tactic unit := |
| 11 | +do to_expr ``(is_monoid_hom.map_one %%f) >>= rewrite_target |
| 12 | +meta def map_mul (f : expr) : tactic unit := |
| 13 | +do to_expr ``(is_mul_hom.map_mul %%f) >>= rewrite_target |
| 14 | +meta def map_inv (f : expr) : tactic unit := |
| 15 | +do to_expr ``(is_group_hom.map_inv %%f) >>= rewrite_target |
| 16 | + |
| 17 | +meta def lookup_homs (n : expr) : tactic (list expr) := |
| 18 | +do ctx ← local_context, |
| 19 | + ctx.mfilter (λ e, to_expr ``(%%n %%e) >>= mk_instance >> pure true <|> pure false) |
| 20 | + |
| 21 | +meta def mul_homs : tactic (list expr) := |
| 22 | +do mh ← mk_const `is_mul_hom, |
| 23 | + lookup_homs mh |
| 24 | +meta def monoid_homs : tactic (list expr) := |
| 25 | +do mh ← mk_const `is_monoid_hom, |
| 26 | + lookup_homs mh |
| 27 | +meta def group_homs : tactic (list expr) := |
| 28 | +do mh ← mk_const `is_group_hom, |
| 29 | + lookup_homs mh |
| 30 | + |
| 31 | +#check rewrite |
| 32 | + |
| 33 | +meta def push_monoid_hom (f : expr) : tactic unit := |
| 34 | +do mul ← to_expr ``(is_monoid_hom.map_mul %%f), |
| 35 | + one ← to_expr ``(is_monoid_hom.map_one %%f), |
| 36 | + chain [rewrite_target one, rewrite_target mul], |
| 37 | + skip |
| 38 | + |
| 39 | +meta def instance_type : name → tactic name |
| 40 | +| `has_mul := pure `is_mul_hom |
| 41 | +| `semigroup := pure `is_semigroup_hom |
| 42 | +| `monoid := pure `is_monoid_hom |
| 43 | +| _ := fail "The `hom` tactic only supports ..." |
| 44 | + |
| 45 | +meta def hom : tactic unit := |
| 46 | +do mul_homs ← mul_homs, |
| 47 | + -- trace mul_homs, |
| 48 | + let mul_tactics := mul_homs.map map_mul, |
| 49 | + monoid_homs ← monoid_homs, |
| 50 | + -- trace monoid_homs, |
| 51 | + let monoid_tactics := monoid_homs.map map_one, |
| 52 | + group_homs ← group_homs, |
| 53 | + -- trace group_homs, |
| 54 | + let group_tactics := group_homs.map map_inv, |
| 55 | + chain $ monoid_tactics ++ mul_tactics ++ group_tactics, |
| 56 | + try reflexivity |
| 57 | + |
| 58 | + |
| 59 | +example (X Y : Type) [ring X] [ring Y] (f : X → Y) [is_monoid_hom f] |
| 60 | + (x y : X) : f (x * y) = f x * f y := |
| 61 | +begin |
| 62 | + hom |
| 63 | +end |
0 commit comments