1use vampire_prover::{Function, Options, Predicate, Problem, ProofRes, Term, exists, forall};
2
3fn main() {
4 let mult = Function::new("mult", 2);
6 let inv = Function::new("inv", 1);
7 let one = Function::constant("1");
8
9 let mul = |x: Term, y: Term| -> Term { mult.with([x, y]) };
11
12 let right_identity = forall(|x| mul(x, one).eq(x));
14
15 let right_inverse = forall(|x| {
17 let inv_x = inv.with(x);
18 mul(x, inv_x).eq(one)
19 });
20
21 let associativity = forall(|x| forall(|y| forall(|z| mul(mul(x, y), z).eq(mul(x, mul(y, z))))));
23
24 let h = Predicate::new("h", 1);
26
27 let h_ident = h.with(one);
29
30 let h_mul_closed = forall(|x| forall(|y| (h.with(x) & h.with(y)) >> h.with(mul(x, y))));
32
33 let h_inv_closed = forall(|x| h.with(x) >> h.with(inv.with(x)));
35
36 let h_index_2 = exists(|x| {
38 let not_in_h = !h.with(x);
40 let class = forall(|y| h.with(y) | h.with(mul(inv.with(x), y)));
42
43 not_in_h & class
44 });
45
46 let h_normal = forall(|x| {
48 let h_x = h.with(x);
49 let conj_x = forall(|y| {
50 let y_inv = inv.with(y);
51 h.with(mul(mul(y, x), y_inv))
52 });
53 h_x.iff(conj_x)
54 });
55
56 let (solution, proof) = Problem::new(Options::new())
57 .with_axiom(right_identity)
58 .with_axiom(right_inverse)
59 .with_axiom(associativity)
60 .with_axiom(h_ident)
61 .with_axiom(h_mul_closed)
62 .with_axiom(h_inv_closed)
63 .with_axiom(h_index_2)
64 .conjecture(h_normal)
65 .solve_and_prove();
66
67 if let Some(proof) = proof {
68 println!("{}", proof);
69 }
70
71 assert_eq!(solution, ProofRes::Proved);
72}