pub enum StreamComponent {
Show 23 variants
ForEach {
class_name: String,
},
ForEachIncludingUnassigned {
class_name: String,
},
ForEachUniquePair {
class_name: String,
joiners: Vec<Joiner>,
},
Filter {
predicate: WasmFunction,
},
Join {
class_name: String,
joiners: Vec<Joiner>,
},
IfExists {
class_name: String,
joiners: Vec<Joiner>,
},
IfNotExists {
class_name: String,
joiners: Vec<Joiner>,
},
IfExistsOther {
class_name: String,
joiners: Vec<Joiner>,
},
IfNotExistsOther {
class_name: String,
joiners: Vec<Joiner>,
},
IfExistsIncludingUnassigned {
class_name: String,
joiners: Vec<Joiner>,
},
IfNotExistsIncludingUnassigned {
class_name: String,
joiners: Vec<Joiner>,
},
GroupBy {
keys: Vec<WasmFunction>,
aggregators: Vec<Collector>,
},
Map {
mappers: Vec<WasmFunction>,
},
FlattenLast {
map: Option<WasmFunction>,
},
Expand {
mappers: Vec<WasmFunction>,
},
Complement {
class_name: String,
},
Penalize {
weight: String,
scale_by: Option<WasmFunction>,
},
Reward {
weight: String,
scale_by: Option<WasmFunction>,
},
Concat {
other_components: Vec<StreamComponent>,
},
Distinct,
Impact {
weight: String,
scale_by: Option<WasmFunction>,
},
IndictWith {
indicted_object_provider: WasmFunction,
},
JustifyWith {
justification_supplier: WasmFunction,
},
}Expand description
A component in a constraint stream pipeline.
Constraint streams transform entity streams through filtering, joining, grouping, and finally scoring. Components chain together to form constraints.
§Pipeline Structure
A typical constraint pipeline:
- Source:
for_each("Lesson")- iterate over entities - Filter:
filter(predicate)- exclude non-matching entities - Join:
join("Timeslot")- combine with another entity type - Score:
penalize("1hard")orreward("1soft")- apply scoring
§Example
use solverforge_core::constraints::StreamComponent;
// Simple penalty: penalize each lesson by 1 hard point
let stream = vec![
StreamComponent::for_each("Lesson"),
StreamComponent::penalize("1hard"),
];
// Unique pair constraint: penalize conflicting lessons
let conflict = vec![
StreamComponent::for_each_unique_pair("Lesson"),
StreamComponent::penalize("1hard"),
];§Score Weights
Weights specify the penalty/reward magnitude:
"1hard"- 1 hard constraint violation"10soft"- 10 soft constraint points"1hard/5soft"- both hard and soft impact
Variants§
ForEach
ForEachIncludingUnassigned
ForEachUniquePair
Filter
Fields
predicate: WasmFunctionJoin
IfExists
IfNotExists
IfExistsOther
IfNotExistsOther
IfExistsIncludingUnassigned
IfNotExistsIncludingUnassigned
GroupBy
Map
Fields
mappers: Vec<WasmFunction>FlattenLast
Fields
map: Option<WasmFunction>Expand
Fields
mappers: Vec<WasmFunction>Complement
Penalize
Reward
Concat
Fields
other_components: Vec<StreamComponent>Distinct
Impact
IndictWith
Fields
indicted_object_provider: WasmFunctionJustifyWith
Fields
justification_supplier: WasmFunctionImplementations§
Source§impl StreamComponent
impl StreamComponent
Sourcepub fn for_each(class_name: impl Into<String>) -> Self
pub fn for_each(class_name: impl Into<String>) -> Self
Iterates over all entities of the given class.
This is the most common way to start a constraint stream. Only considers entities with assigned planning variables.
use solverforge_core::constraints::StreamComponent;
let source = StreamComponent::for_each("Lesson");pub fn for_each_including_unassigned(class_name: impl Into<String>) -> Self
Sourcepub fn for_each_unique_pair(class_name: impl Into<String>) -> Self
pub fn for_each_unique_pair(class_name: impl Into<String>) -> Self
Iterates over all unique pairs of entities of the given class.
Use this for constraints that compare two entities of the same type, like detecting room conflicts between lessons.
use solverforge_core::constraints::StreamComponent;
// Pairs: (A,B), (A,C), (B,C) - no duplicates like (B,A)
let pairs = StreamComponent::for_each_unique_pair("Lesson");pub fn for_each_unique_pair_with_joiners( class_name: impl Into<String>, joiners: Vec<Joiner>, ) -> Self
pub fn filter(predicate: WasmFunction) -> Self
pub fn join(class_name: impl Into<String>) -> Self
pub fn join_with_joiners( class_name: impl Into<String>, joiners: Vec<Joiner>, ) -> Self
pub fn if_exists(class_name: impl Into<String>) -> Self
pub fn if_exists_with_joiners( class_name: impl Into<String>, joiners: Vec<Joiner>, ) -> Self
pub fn if_not_exists(class_name: impl Into<String>) -> Self
pub fn if_not_exists_with_joiners( class_name: impl Into<String>, joiners: Vec<Joiner>, ) -> Self
pub fn if_exists_other(class_name: impl Into<String>) -> Self
pub fn if_exists_other_with_joiners( class_name: impl Into<String>, joiners: Vec<Joiner>, ) -> Self
pub fn if_not_exists_other(class_name: impl Into<String>) -> Self
pub fn if_not_exists_other_with_joiners( class_name: impl Into<String>, joiners: Vec<Joiner>, ) -> Self
pub fn if_exists_including_unassigned(class_name: impl Into<String>) -> Self
pub fn if_exists_including_unassigned_with_joiners( class_name: impl Into<String>, joiners: Vec<Joiner>, ) -> Self
pub fn if_not_exists_including_unassigned(class_name: impl Into<String>) -> Self
pub fn if_not_exists_including_unassigned_with_joiners( class_name: impl Into<String>, joiners: Vec<Joiner>, ) -> Self
pub fn group_by(keys: Vec<WasmFunction>, aggregators: Vec<Collector>) -> Self
pub fn group_by_key(key: WasmFunction) -> Self
pub fn group_by_collector(aggregator: Collector) -> Self
pub fn map(mappers: Vec<WasmFunction>) -> Self
pub fn map_single(mapper: WasmFunction) -> Self
pub fn flatten_last() -> Self
pub fn flatten_last_with_map(map: WasmFunction) -> Self
pub fn expand(mappers: Vec<WasmFunction>) -> Self
pub fn complement(class_name: impl Into<String>) -> Self
Sourcepub fn penalize(weight: impl Into<String>) -> Self
pub fn penalize(weight: impl Into<String>) -> Self
Penalizes matching entities by a fixed weight.
The weight reduces the solution score. Higher penalties are worse.
use solverforge_core::constraints::StreamComponent;
// Hard constraint: 1 point per violation
let hard = StreamComponent::penalize("1hard");
// Soft constraint: 100 points per violation
let soft = StreamComponent::penalize("100soft");pub fn penalize_with_weigher( weight: impl Into<String>, scale_by: WasmFunction, ) -> Self
Sourcepub fn reward(weight: impl Into<String>) -> Self
pub fn reward(weight: impl Into<String>) -> Self
Rewards matching entities by a fixed weight.
The weight increases the solution score. Higher rewards are better.
use solverforge_core::constraints::StreamComponent;
// Reward preferred assignments
let bonus = StreamComponent::reward("10soft");pub fn reward_with_weigher( weight: impl Into<String>, scale_by: WasmFunction, ) -> Self
pub fn concat(other_components: Vec<StreamComponent>) -> Self
pub fn distinct() -> Self
pub fn impact(weight: impl Into<String>) -> Self
pub fn impact_with_weigher( weight: impl Into<String>, scale_by: WasmFunction, ) -> Self
pub fn indict_with(indicted_object_provider: WasmFunction) -> Self
pub fn indict_with_expr(indicted_object_provider: NamedExpression) -> Self
pub fn justify_with(justification_supplier: WasmFunction) -> Self
pub fn justify_with_expr(justification_supplier: NamedExpression) -> Self
Sourcepub fn filter_expr(expr: NamedExpression) -> Self
pub fn filter_expr(expr: NamedExpression) -> Self
Creates a filter component from a named expression.
§Example
use solverforge_core::wasm::{Expr, FieldAccessExt};
use solverforge_core::constraints::{StreamComponent, IntoNamedExpression};
let has_room = Expr::is_not_null(Expr::param(0).get("Lesson", "room"))
.named_as("has_room");
let filter = StreamComponent::filter_expr(has_room);
assert!(matches!(filter, StreamComponent::Filter { .. }));Sourcepub fn map_expr(mappers: Vec<NamedExpression>) -> Self
pub fn map_expr(mappers: Vec<NamedExpression>) -> Self
Creates a map component from named expressions.
Sourcepub fn map_single_expr(mapper: NamedExpression) -> Self
pub fn map_single_expr(mapper: NamedExpression) -> Self
Creates a single-mapper map component from a named expression.
Sourcepub fn group_by_expr(
keys: Vec<NamedExpression>,
aggregators: Vec<Collector>,
) -> Self
pub fn group_by_expr( keys: Vec<NamedExpression>, aggregators: Vec<Collector>, ) -> Self
Creates a groupBy component with expression-based key extractors.
Sourcepub fn group_by_key_expr(key: NamedExpression) -> Self
pub fn group_by_key_expr(key: NamedExpression) -> Self
Creates a groupBy component with a single expression-based key.
Sourcepub fn penalize_with_expr(
weight: impl Into<String>,
scale_by: NamedExpression,
) -> Self
pub fn penalize_with_expr( weight: impl Into<String>, scale_by: NamedExpression, ) -> Self
Creates a penalize component with an expression-based weigher.
Sourcepub fn reward_with_expr(
weight: impl Into<String>,
scale_by: NamedExpression,
) -> Self
pub fn reward_with_expr( weight: impl Into<String>, scale_by: NamedExpression, ) -> Self
Creates a reward component with an expression-based weigher.
Sourcepub fn flatten_last_with_expr(map: NamedExpression) -> Self
pub fn flatten_last_with_expr(map: NamedExpression) -> Self
Creates a flattenLast component with an expression-based mapper.
Sourcepub fn expand_expr(mappers: Vec<NamedExpression>) -> Self
pub fn expand_expr(mappers: Vec<NamedExpression>) -> Self
Creates an expand component from named expressions.
Sourcepub fn impact_with_expr(
weight: impl Into<String>,
scale_by: NamedExpression,
) -> Self
pub fn impact_with_expr( weight: impl Into<String>, scale_by: NamedExpression, ) -> Self
Creates an impact component with an expression-based weigher.
Trait Implementations§
Source§impl Clone for StreamComponent
impl Clone for StreamComponent
Source§fn clone(&self) -> StreamComponent
fn clone(&self) -> StreamComponent
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for StreamComponent
impl Debug for StreamComponent
Source§impl<'de> Deserialize<'de> for StreamComponent
impl<'de> Deserialize<'de> for StreamComponent
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl PartialEq for StreamComponent
impl PartialEq for StreamComponent
Source§impl Serialize for StreamComponent
impl Serialize for StreamComponent
impl Eq for StreamComponent
impl StructuralPartialEq for StreamComponent
Auto Trait Implementations§
impl Freeze for StreamComponent
impl RefUnwindSafe for StreamComponent
impl Send for StreamComponent
impl Sync for StreamComponent
impl Unpin for StreamComponent
impl UnwindSafe for StreamComponent
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
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.