pub struct Predicate { /* private fields */ }Expand description
A predicate symbol in first-order logic.
Predicates represent relations or properties that can be true or false. They take terms as arguments and produce formulas. Like functions, predicates have a fixed arity.
§Examples
use vampire_prover::{Function, Predicate};
// Unary predicate (property)
let is_mortal = Predicate::new("mortal", 1);
let socrates = Function::constant("socrates");
let formula = is_mortal.with(socrates); // mortal(socrates)
// Binary predicate (relation)
let loves = Predicate::new("loves", 2);
let alice = Function::constant("alice");
let bob = Function::constant("bob");
let formula = loves.with([alice, bob]); // loves(alice, bob)Implementations§
Source§impl Predicate
impl Predicate
Sourcepub fn new(name: &str, arity: u32) -> Self
pub fn new(name: &str, arity: u32) -> Self
Creates a new predicate symbol with the given name and arity.
Calling this method multiple times with the same name and arity will return the same predicate symbol. It is safe to call this with the same name but different arities - they will be treated as distinct predicate symbols.
§Arguments
name- The name of the predicate symbolarity- The number of arguments this predicate takes
§Examples
use vampire_prover::Predicate;
let edge = Predicate::new("edge", 2);
assert_eq!(edge.arity(), 2);
// Same name and arity returns the same symbol
let edge2 = Predicate::new("edge", 2);
assert_eq!(edge, edge2);
// Same name but different arity is a different symbol
let edge3 = Predicate::new("edge", 3);
assert_ne!(edge.arity(), edge3.arity());Examples found in repository?
examples/bench_index2.rs (line 109)
106fn waste_symbols(i: usize) {
107 for j in 0..1000 {
108 Function::new(&format!("p{i}-{j}"), 2);
109 Predicate::new(&format!("f{i}-{j}"), 2);
110 }
111}
112
113fn run_proof(i: usize) -> ProofRes {
114 // Prove that every subgroup of index 2 is normal.
115 let mult = Function::new(&format!("mult{i}"), 2);
116 let inv = Function::new(&format!("inv{i}"), 1);
117 let one = Function::constant(&format!("1{i}"));
118
119 // Helper to make multiplication more readable
120 let mul = |x: Term, y: Term| -> Term { mult.with(&[x, y]) };
121
122 // Group Axiom 1: Right identity - ∀x. x * 1 = x
123 let right_identity = forall(|x| mul(x, one).eq(x));
124
125 // Group Axiom 2: Right inverse - ∀x. x * inv(x) = 1
126 let right_inverse = forall(|x| {
127 let inv_x = inv.with(&[x]);
128 mul(x, inv_x).eq(one)
129 });
130
131 // Group Axiom 3: Associativity - ∀x,y,z. (x * y) * z = x * (y * z)
132 let associativity = forall(|x| forall(|y| forall(|z| mul(mul(x, y), z).eq(mul(x, mul(y, z))))));
133
134 // Describe the subgroup
135 let h = Predicate::new("h", 1);
136
137 // Any subgroup contains the identity
138 let h_ident = h.with(&[one]);
139
140 // And is closed under multiplication
141 let h_mul_closed =
142 forall(|x| forall(|y| (h.with(&[x]) & h.with(&[y])) >> h.with(&[mul(x, y)])));
143
144 // And is closed under inverse
145 let h_inv_closed = forall(|x| h.with(&[x]) >> h.with(&[inv.with(&[x])]));
146
147 // H specifically is of order 2
148 let h_index_2 = exists(|x| {
149 // an element not in H
150 let not_in_h = !h.with(&[x]);
151 // but everything is in H or x H
152 let class = forall(|y| h.with(&[y]) | h.with(&[mul(inv.with(&[x]), y)]));
153
154 not_in_h & class
155 });
156
157 // Conjecture: H is normal
158 let h_normal = forall(|x| {
159 let h_x = h.with(&[x]);
160 let conj_x = forall(|y| {
161 let y_inv = inv.with(&[y]);
162 h.with(&[mul(mul(y, x), y_inv)])
163 });
164 h_x.iff(conj_x)
165 });
166
167 Problem::new(Options::new())
168 .with_axiom(right_identity)
169 .with_axiom(right_inverse)
170 .with_axiom(associativity)
171 .with_axiom(h_ident)
172 .with_axiom(h_mul_closed)
173 .with_axiom(h_inv_closed)
174 .with_axiom(h_index_2)
175 .conjecture(h_normal)
176 .solve()
177}More examples
examples/name_reuse.rs (line 16)
3fn main() {
4 let x1 = Function::new("x", 0);
5 let x2 = Function::new("x", 0);
6
7 dbg!(x1, x2);
8 dbg!(x1 == x2);
9
10 let y1 = Function::new("y", 0);
11 let y2 = Function::new("y", 1);
12
13 dbg!(y1, y2);
14
15 let z1 = Function::new("z", 0);
16 let z2 = Predicate::new("z", 0);
17
18 dbg!(z1, z2);
19
20 let solution = Problem::new(Options::new())
21 .with_axiom(y1.with(&[]).eq(y2.with(&[y1.with(&[])])))
22 .solve();
23
24 dbg!(solution);
25}examples/group2.rs (line 25)
3fn main() {
4 // Prove that every subgroup of index 2 is normal.
5 let mult = Function::new("mult", 2);
6 let inv = Function::new("inv", 1);
7 let one = Function::constant("1");
8
9 // Helper to make multiplication more readable
10 let mul = |x: Term, y: Term| -> Term { mult.with([x, y]) };
11
12 // Group Axiom 1: Right identity - ∀x. x * 1 = x
13 let right_identity = forall(|x| mul(x, one).eq(x));
14
15 // Group Axiom 2: Right inverse - ∀x. x * inv(x) = 1
16 let right_inverse = forall(|x| {
17 let inv_x = inv.with(x);
18 mul(x, inv_x).eq(one)
19 });
20
21 // Group Axiom 3: Associativity - ∀x,y,z. (x * y) * z = x * (y * z)
22 let associativity = forall(|x| forall(|y| forall(|z| mul(mul(x, y), z).eq(mul(x, mul(y, z))))));
23
24 // Describe the subgroup
25 let h = Predicate::new("h", 1);
26
27 // Any subgroup contains the identity
28 let h_ident = h.with(one);
29
30 // And is closed under multiplication
31 let h_mul_closed = forall(|x| forall(|y| (h.with(x) & h.with(y)) >> h.with(mul(x, y))));
32
33 // And is closed under inverse
34 let h_inv_closed = forall(|x| h.with(x) >> h.with(inv.with(x)));
35
36 // H specifically is of order 2
37 let h_index_2 = exists(|x| {
38 // an element not in H
39 let not_in_h = !h.with(x);
40 // but everything is in H or x H
41 let class = forall(|y| h.with(y) | h.with(mul(inv.with(x), y)));
42
43 not_in_h & class
44 });
45
46 // Conjecture: H is normal
47 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}Sourcepub fn arity(&self) -> u32
pub fn arity(&self) -> u32
Returns the arity (number of arguments) of this predicate.
§Examples
use vampire_prover::Predicate;
let p = Predicate::new("p", 2);
assert_eq!(p.arity(), 2);Sourcepub fn with(&self, args: impl IntoTermArgs) -> Formula
pub fn with(&self, args: impl IntoTermArgs) -> Formula
Applies this predicate to the given arguments, creating a formula.
This method accepts multiple argument formats for convenience:
- Single term:
p.with(x) - Array:
p.with([x, y])
§Panics
Panics if the number of arguments does not match the predicate’s arity.
§Examples
use vampire_prover::{Function, Predicate};
let mortal = Predicate::new("mortal", 1);
let socrates = Function::constant("socrates");
// Single argument:
let formula = mortal.with(socrates);
// Multiple arguments:
let edge = Predicate::new("edge", 2);
let a = Function::constant("a");
let b = Function::constant("b");
let e = edge.with([a, b]);Examples found in repository?
examples/bench_index2.rs (line 138)
113fn run_proof(i: usize) -> ProofRes {
114 // Prove that every subgroup of index 2 is normal.
115 let mult = Function::new(&format!("mult{i}"), 2);
116 let inv = Function::new(&format!("inv{i}"), 1);
117 let one = Function::constant(&format!("1{i}"));
118
119 // Helper to make multiplication more readable
120 let mul = |x: Term, y: Term| -> Term { mult.with(&[x, y]) };
121
122 // Group Axiom 1: Right identity - ∀x. x * 1 = x
123 let right_identity = forall(|x| mul(x, one).eq(x));
124
125 // Group Axiom 2: Right inverse - ∀x. x * inv(x) = 1
126 let right_inverse = forall(|x| {
127 let inv_x = inv.with(&[x]);
128 mul(x, inv_x).eq(one)
129 });
130
131 // Group Axiom 3: Associativity - ∀x,y,z. (x * y) * z = x * (y * z)
132 let associativity = forall(|x| forall(|y| forall(|z| mul(mul(x, y), z).eq(mul(x, mul(y, z))))));
133
134 // Describe the subgroup
135 let h = Predicate::new("h", 1);
136
137 // Any subgroup contains the identity
138 let h_ident = h.with(&[one]);
139
140 // And is closed under multiplication
141 let h_mul_closed =
142 forall(|x| forall(|y| (h.with(&[x]) & h.with(&[y])) >> h.with(&[mul(x, y)])));
143
144 // And is closed under inverse
145 let h_inv_closed = forall(|x| h.with(&[x]) >> h.with(&[inv.with(&[x])]));
146
147 // H specifically is of order 2
148 let h_index_2 = exists(|x| {
149 // an element not in H
150 let not_in_h = !h.with(&[x]);
151 // but everything is in H or x H
152 let class = forall(|y| h.with(&[y]) | h.with(&[mul(inv.with(&[x]), y)]));
153
154 not_in_h & class
155 });
156
157 // Conjecture: H is normal
158 let h_normal = forall(|x| {
159 let h_x = h.with(&[x]);
160 let conj_x = forall(|y| {
161 let y_inv = inv.with(&[y]);
162 h.with(&[mul(mul(y, x), y_inv)])
163 });
164 h_x.iff(conj_x)
165 });
166
167 Problem::new(Options::new())
168 .with_axiom(right_identity)
169 .with_axiom(right_inverse)
170 .with_axiom(associativity)
171 .with_axiom(h_ident)
172 .with_axiom(h_mul_closed)
173 .with_axiom(h_inv_closed)
174 .with_axiom(h_index_2)
175 .conjecture(h_normal)
176 .solve()
177}More examples
examples/group2.rs (line 28)
3fn main() {
4 // Prove that every subgroup of index 2 is normal.
5 let mult = Function::new("mult", 2);
6 let inv = Function::new("inv", 1);
7 let one = Function::constant("1");
8
9 // Helper to make multiplication more readable
10 let mul = |x: Term, y: Term| -> Term { mult.with([x, y]) };
11
12 // Group Axiom 1: Right identity - ∀x. x * 1 = x
13 let right_identity = forall(|x| mul(x, one).eq(x));
14
15 // Group Axiom 2: Right inverse - ∀x. x * inv(x) = 1
16 let right_inverse = forall(|x| {
17 let inv_x = inv.with(x);
18 mul(x, inv_x).eq(one)
19 });
20
21 // Group Axiom 3: Associativity - ∀x,y,z. (x * y) * z = x * (y * z)
22 let associativity = forall(|x| forall(|y| forall(|z| mul(mul(x, y), z).eq(mul(x, mul(y, z))))));
23
24 // Describe the subgroup
25 let h = Predicate::new("h", 1);
26
27 // Any subgroup contains the identity
28 let h_ident = h.with(one);
29
30 // And is closed under multiplication
31 let h_mul_closed = forall(|x| forall(|y| (h.with(x) & h.with(y)) >> h.with(mul(x, y))));
32
33 // And is closed under inverse
34 let h_inv_closed = forall(|x| h.with(x) >> h.with(inv.with(x)));
35
36 // H specifically is of order 2
37 let h_index_2 = exists(|x| {
38 // an element not in H
39 let not_in_h = !h.with(x);
40 // but everything is in H or x H
41 let class = forall(|y| h.with(y) | h.with(mul(inv.with(x), y)));
42
43 not_in_h & class
44 });
45
46 // Conjecture: H is normal
47 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}Trait Implementations§
impl Copy for Predicate
impl Eq for Predicate
impl StructuralPartialEq for Predicate
Auto Trait Implementations§
impl Freeze for Predicate
impl RefUnwindSafe for Predicate
impl Send for Predicate
impl Sync for Predicate
impl Unpin for Predicate
impl UnsafeUnpin for Predicate
impl UnwindSafe for Predicate
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more