Constraint

Struct Constraint 

Source
pub struct Constraint { /* private fields */ }
Expand description

A constraint that can be posted to the model

Implementations§

Source§

impl Constraint

Source

pub fn and(self, other: Constraint) -> Constraint

Combine this constraint with another using AND logic

Examples found in repository?
examples/runtime_api_demo.rs (line 150)
137fn example_4_constraint_composition() {
138    println!("📝 Example 4: Constraint Composition");
139    
140    let mut m = Model::default();
141    let x = m.int(0, 20);
142    let y = m.int(0, 20);
143    
144    // Create individual constraints
145    let c1 = x.gt(int(5));      // x > int(5)
146    let c2 = x.lt(int(15));     // x < int(15)  
147    let c3 = y.ge(int(10));     // y >= int(10)
148    
149    // Compose them: (x > 5 AND x < 15) AND y >= 10
150    let range_constraint = c1.and(c2);
151    let combined = range_constraint.and(c3);
152    
153    m.post(combined);
154    
155    if let Ok(solution) = m.solve() {
156        println!("✓ Solution with composed constraints:");
157        println!("  x = {:?} (should be 6-14)", solution[x]);
158        println!("  y = {:?} (should be >= 10)", solution[y]);
159    } else {
160        println!("❌ No solution found");
161    }
162    println!();
163}
164
165// =================== PHASE 2 EXAMPLES ===================
166
167/// Example 5: Model::c() ultra-short syntax
168fn example_5_model_c_syntax() {
169    println!("📝 Example 5: Model::c() Ultra-Short Syntax (Phase 2)");
170    
171    let mut m = Model::default();
172    let x = m.int(1, 10);
173    let y = m.int(1, 10);
174    let sum = m.int(2, 20);
175    
176    // Ultra-short Model::c() syntax - auto-posts constraints
177    m.c(x).gt(int(3));                    // x > int(3)
178    m.c(y).le(int(8));                    // y <= int(8)
179    m.c(x).add(y).eq(sum);               // x + y == sum
180    m.c(sum).eq(int(12));                // sum == int(12)
181    
182    if let Ok(solution) = m.solve() {
183        println!("✓ Solution found:");
184        println!("  x = {:?}", solution[x]);
185        println!("  y = {:?}", solution[y]);
186        println!("  sum = {:?}", solution[sum]);
187    } else {
188        println!("❌ No solution found");
189    }
190    println!();
191}
192
193/// Example 6: Builder fluent interface
194fn example_6_builder_fluent_interface() {
195    println!("📝 Example 6: Builder Fluent Interface (Phase 2)");
196    
197    let mut m = Model::default();
198    let a = m.int(0, 20);
199    let b = m.int(0, 20);
200    let result = m.int(0, 100);
201    
202    // Complex expression building with fluent interface
203    m.c(a).mul(int(3)).add(int(5)).le(int(50));         // a * int(3) + int(5) <= int(50)
204    m.c(b).div(int(2)).sub(int(1)).ge(int(2));          // b / int(2) - int(1) >= int(2)
205    m.c(a).add(b).mul(int(2)).eq(result);              // (a + b) * int(2) == result
206    m.c(result).ne(int(20));                           // result != int(20)
207    
208    if let Ok(solution) = m.solve() {
209        println!("✓ Complex fluent constraints satisfied:");
210        println!("  a = {:?}", solution[a]);
211        println!("  b = {:?}", solution[b]);
212        println!("  result = {:?}", solution[result]);
213    } else {
214        println!("❌ No solution found");
215    }
216    println!();
217}
218
219/// Example 7: Global constraint shortcuts
220fn example_7_global_constraints() {
221    println!("📝 Example 7: Global Constraint Shortcuts (Phase 2)");
222    
223    let mut m = Model::default();
224    let digits = (0..4).map(|_| m.int(1, 4)).collect::<Vec<_>>();
225    
226    // Ultra-short global constraints
227    m.alldiff(&digits);              // All digits must be different
228    m.c(digits[0]).gt(digits[1]);    // First > Second
229    m.c(digits[2]).add(digits[3]).eq(int(5)); // Third + Fourth == int(5)
230    
231    if let Ok(solution) = m.solve() {
232        println!("✓ Global constraint solution:");
233        for (i, &digit) in digits.iter().enumerate() {
234            println!("  digit[{}] = {:?}", i, solution[digit]);
235        }
236    } else {
237        println!("❌ No solution found");
238    }
239    println!();
240}
241
242/// Example 8: Mixed Phase 1 & 2 usage
243fn example_8_mixed_phase_usage() {
244    println!("📝 Example 8: Mixed Phase 1 & 2 Usage");
245    
246    let mut m = Model::default();
247    let x = m.int(1, 10);
248    let y = m.int(1, 10);
249    let z = m.int(1, 10);
250    
251    // Phase 1: Manual constraint creation and posting
252    let constraint1 = x.add(y).gt(int(5));
253    m.post(constraint1);
254    
255    // Phase 2: Auto-posting builder syntax
256    m.c(y).mul(int(2)).le(z.add(int(3)));
257    
258    // Global constraints (Phase 2)
259    m.alldiff(&[x, y, z]);
260    
261    // Phase 1: Complex constraint composition  
262    let c1 = x.lt(int(8));
263    let c2 = y.ge(int(2));
264    let combined = c1.and(c2);
265    m.post(combined);
266    
267    if let Ok(solution) = m.solve() {
268        println!("✓ Mixed API solution:");
269        println!("  x = {:?}", solution[x]);
270        println!("  y = {:?}", solution[y]);
271        println!("  z = {:?}", solution[z]);
272    } else {
273        println!("❌ No solution found");
274    }
275    println!();
276}
Source

pub fn or(self, other: Constraint) -> Constraint

Combine this constraint with another using OR logic

Source

pub fn not(self) -> Constraint

Negate this constraint

Source§

impl Constraint

Source

pub fn and_all(constraints: Vec<Constraint>) -> Option<Constraint>

Combine multiple constraints with AND logic

Source

pub fn or_all(constraints: Vec<Constraint>) -> Option<Constraint>

Combine multiple constraints with OR logic

Trait Implementations§

Source§

impl Clone for Constraint

Source§

fn clone(&self) -> Constraint

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.