in core/optaplanner-core-impl/src/main/java/org/optaplanner/core/api/score/stream/quad/QuadConstraintStream.java [429:825]
<E> QuadConstraintStream<A, B, C, D> ifNotExistsIncludingNullVars(Class<E> otherClass,
PentaJoiner<A, B, C, D, E>... joiners);
// ************************************************************************
// Group by
// ************************************************************************
/**
* Convert the {@link QuadConstraintStream} to a {@link UniConstraintStream}, containing only a single tuple, the
* result of applying {@link QuadConstraintCollector}.
* {@link UniConstraintStream} which only has a single tuple, the result of applying
* {@link QuadConstraintCollector}.
*
* @param collector never null, the collector to perform the grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param <ResultContainer_> the mutable accumulation type (often hidden as an implementation detail)
* @param <Result_> the type of a fact in the destination {@link UniConstraintStream}'s tuple
* @return never null
*/
<ResultContainer_, Result_> UniConstraintStream<Result_> groupBy(
QuadConstraintCollector<A, B, C, D, ResultContainer_, Result_> collector);
/**
* Convert the {@link QuadConstraintStream} to a {@link BiConstraintStream}, containing only a single tuple,
* the result of applying two {@link QuadConstraintCollector}s.
*
* @param collectorA never null, the collector to perform the first grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param collectorB never null, the collector to perform the second grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param <ResultContainerA_> the mutable accumulation type (often hidden as an implementation detail)
* @param <ResultA_> the type of the first fact in the destination {@link BiConstraintStream}'s tuple
* @param <ResultContainerB_> the mutable accumulation type (often hidden as an implementation detail)
* @param <ResultB_> the type of the second fact in the destination {@link BiConstraintStream}'s tuple
* @return never null
*/
<ResultContainerA_, ResultA_, ResultContainerB_, ResultB_> BiConstraintStream<ResultA_, ResultB_> groupBy(
QuadConstraintCollector<A, B, C, D, ResultContainerA_, ResultA_> collectorA,
QuadConstraintCollector<A, B, C, D, ResultContainerB_, ResultB_> collectorB);
/**
* Convert the {@link QuadConstraintStream} to a {@link TriConstraintStream}, containing only a single tuple,
* the result of applying three {@link QuadConstraintCollector}s.
*
* @param collectorA never null, the collector to perform the first grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param collectorB never null, the collector to perform the second grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param collectorC never null, the collector to perform the third grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param <ResultContainerA_> the mutable accumulation type (often hidden as an implementation detail)
* @param <ResultA_> the type of the first fact in the destination {@link TriConstraintStream}'s tuple
* @param <ResultContainerB_> the mutable accumulation type (often hidden as an implementation detail)
* @param <ResultB_> the type of the second fact in the destination {@link TriConstraintStream}'s tuple
* @param <ResultContainerC_> the mutable accumulation type (often hidden as an implementation detail)
* @param <ResultC_> the type of the third fact in the destination {@link TriConstraintStream}'s tuple
* @return never null
*/
<ResultContainerA_, ResultA_, ResultContainerB_, ResultB_, ResultContainerC_, ResultC_>
TriConstraintStream<ResultA_, ResultB_, ResultC_> groupBy(
QuadConstraintCollector<A, B, C, D, ResultContainerA_, ResultA_> collectorA,
QuadConstraintCollector<A, B, C, D, ResultContainerB_, ResultB_> collectorB,
QuadConstraintCollector<A, B, C, D, ResultContainerC_, ResultC_> collectorC);
/**
* Convert the {@link QuadConstraintStream} to a {@link QuadConstraintStream}, containing only a single tuple,
* the result of applying four {@link QuadConstraintCollector}s.
*
* @param collectorA never null, the collector to perform the first grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param collectorB never null, the collector to perform the second grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param collectorC never null, the collector to perform the third grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param collectorD never null, the collector to perform the fourth grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param <ResultContainerA_> the mutable accumulation type (often hidden as an implementation detail)
* @param <ResultA_> the type of the first fact in the destination {@link QuadConstraintStream}'s tuple
* @param <ResultContainerB_> the mutable accumulation type (often hidden as an implementation detail)
* @param <ResultB_> the type of the second fact in the destination {@link QuadConstraintStream}'s tuple
* @param <ResultContainerC_> the mutable accumulation type (often hidden as an implementation detail)
* @param <ResultC_> the type of the third fact in the destination {@link QuadConstraintStream}'s tuple
* @param <ResultContainerD_> the mutable accumulation type (often hidden as an implementation detail)
* @param <ResultD_> the type of the fourth fact in the destination {@link QuadConstraintStream}'s tuple
* @return never null
*/
<ResultContainerA_, ResultA_, ResultContainerB_, ResultB_, ResultContainerC_, ResultC_, ResultContainerD_, ResultD_>
QuadConstraintStream<ResultA_, ResultB_, ResultC_, ResultD_> groupBy(
QuadConstraintCollector<A, B, C, D, ResultContainerA_, ResultA_> collectorA,
QuadConstraintCollector<A, B, C, D, ResultContainerB_, ResultB_> collectorB,
QuadConstraintCollector<A, B, C, D, ResultContainerC_, ResultC_> collectorC,
QuadConstraintCollector<A, B, C, D, ResultContainerD_, ResultD_> collectorD);
/**
* Convert the {@link QuadConstraintStream} to a {@link UniConstraintStream}, containing the set of tuples resulting
* from applying the group key mapping function on all tuples of the original stream.
* Neither tuple of the new stream {@link Objects#equals(Object, Object)} any other.
*
* @param groupKeyMapping never null, mapping function to convert each element in the stream to a different element
* @param <GroupKey_> the type of a fact in the destination {@link UniConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @return never null
*/
<GroupKey_> UniConstraintStream<GroupKey_> groupBy(QuadFunction<A, B, C, D, GroupKey_> groupKeyMapping);
/**
* Convert the {@link QuadConstraintStream} to a {@link BiConstraintStream}, consisting of unique tuples.
* <p>
* The first fact is the return value of the group key mapping function, applied on the incoming tuple.
* The second fact is the return value of a given {@link QuadConstraintCollector} applied on all incoming tuples
* with the same first fact.
*
* @param groupKeyMapping never null, function to convert the fact in the original tuple to a different fact
* @param collector never null, the collector to perform the grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param <GroupKey_> the type of the first fact in the destination {@link BiConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @param <ResultContainer_> the mutable accumulation type (often hidden as an implementation detail)
* @param <Result_> the type of the second fact in the destination {@link BiConstraintStream}'s tuple
* @return never null
*/
<GroupKey_, ResultContainer_, Result_> BiConstraintStream<GroupKey_, Result_> groupBy(
QuadFunction<A, B, C, D, GroupKey_> groupKeyMapping,
QuadConstraintCollector<A, B, C, D, ResultContainer_, Result_> collector);
/**
* Convert the {@link QuadConstraintStream} to a {@link TriConstraintStream}, consisting of unique tuples with three
* facts.
* <p>
* The first fact is the return value of the group key mapping function, applied on the incoming tuple.
* The remaining facts are the return value of the respective {@link QuadConstraintCollector} applied on all
* incoming tuples with the same first fact.
*
* @param groupKeyMapping never null, function to convert the fact in the original tuple to a different fact
* @param collectorB never null, the collector to perform the first grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param collectorC never null, the collector to perform the second grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param <GroupKey_> the type of the first fact in the destination {@link TriConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @param <ResultContainerB_> the mutable accumulation type (often hidden as an implementation detail)
* @param <ResultB_> the type of the second fact in the destination {@link TriConstraintStream}'s tuple
* @param <ResultContainerC_> the mutable accumulation type (often hidden as an implementation detail)
* @param <ResultC_> the type of the third fact in the destination {@link TriConstraintStream}'s tuple
* @return never null
*/
<GroupKey_, ResultContainerB_, ResultB_, ResultContainerC_, ResultC_>
TriConstraintStream<GroupKey_, ResultB_, ResultC_> groupBy(
QuadFunction<A, B, C, D, GroupKey_> groupKeyMapping,
QuadConstraintCollector<A, B, C, D, ResultContainerB_, ResultB_> collectorB,
QuadConstraintCollector<A, B, C, D, ResultContainerC_, ResultC_> collectorC);
/**
* Convert the {@link QuadConstraintStream} to a {@link QuadConstraintStream}, consisting of unique tuples with four
* facts.
* <p>
* The first fact is the return value of the group key mapping function, applied on the incoming tuple.
* The remaining facts are the return value of the respective {@link QuadConstraintCollector} applied on all
* incoming tuples with the same first fact.
*
* @param groupKeyMapping never null, function to convert the fact in the original tuple to a different fact
* @param collectorB never null, the collector to perform the first grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param collectorC never null, the collector to perform the second grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param collectorD never null, the collector to perform the third grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param <GroupKey_> the type of the first fact in the destination {@link QuadConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @param <ResultContainerB_> the mutable accumulation type (often hidden as an implementation detail)
* @param <ResultB_> the type of the second fact in the destination {@link QuadConstraintStream}'s tuple
* @param <ResultContainerC_> the mutable accumulation type (often hidden as an implementation detail)
* @param <ResultC_> the type of the third fact in the destination {@link QuadConstraintStream}'s tuple
* @param <ResultContainerD_> the mutable accumulation type (often hidden as an implementation detail)
* @param <ResultD_> the type of the fourth fact in the destination {@link QuadConstraintStream}'s tuple
* @return never null
*/
<GroupKey_, ResultContainerB_, ResultB_, ResultContainerC_, ResultC_, ResultContainerD_, ResultD_>
QuadConstraintStream<GroupKey_, ResultB_, ResultC_, ResultD_> groupBy(
QuadFunction<A, B, C, D, GroupKey_> groupKeyMapping,
QuadConstraintCollector<A, B, C, D, ResultContainerB_, ResultB_> collectorB,
QuadConstraintCollector<A, B, C, D, ResultContainerC_, ResultC_> collectorC,
QuadConstraintCollector<A, B, C, D, ResultContainerD_, ResultD_> collectorD);
/**
* Convert the {@link QuadConstraintStream} to a {@link BiConstraintStream}, consisting of unique tuples.
* <p>
* The first fact is the return value of the first group key mapping function, applied on the incoming tuple.
* The second fact is the return value of the second group key mapping function, applied on all incoming tuples with
* the same first fact.
*
* @param groupKeyAMapping never null, function to convert the facts in the original tuple to a new fact
* @param groupKeyBMapping never null, function to convert the facts in the original tuple to another new fact
* @param <GroupKeyA_> the type of the first fact in the destination {@link BiConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @param <GroupKeyB_> the type of the second fact in the destination {@link BiConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @return never null
*/
<GroupKeyA_, GroupKeyB_> BiConstraintStream<GroupKeyA_, GroupKeyB_> groupBy(
QuadFunction<A, B, C, D, GroupKeyA_> groupKeyAMapping, QuadFunction<A, B, C, D, GroupKeyB_> groupKeyBMapping);
/**
* Combines the semantics of {@link #groupBy(QuadFunction, QuadFunction)} and
* {@link #groupBy(QuadConstraintCollector)}.
* That is, the first and second facts in the tuple follow the {@link #groupBy(QuadFunction, QuadFunction)}
* semantics,
* and the third fact is the result of applying {@link QuadConstraintCollector#finisher()} on all the tuples of the
* original {@link UniConstraintStream} that belong to the group.
*
* @param groupKeyAMapping never null, function to convert the original tuple into a first fact
* @param groupKeyBMapping never null, function to convert the original tuple into a second fact
* @param collector never null, the collector to perform the grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param <GroupKeyA_> the type of the first fact in the destination {@link TriConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @param <GroupKeyB_> the type of the second fact in the destination {@link TriConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @param <ResultContainer_> the mutable accumulation type (often hidden as an implementation detail)
* @param <Result_> the type of the third fact in the destination {@link TriConstraintStream}'s tuple
* @return never null
*/
<GroupKeyA_, GroupKeyB_, ResultContainer_, Result_> TriConstraintStream<GroupKeyA_, GroupKeyB_, Result_> groupBy(
QuadFunction<A, B, C, D, GroupKeyA_> groupKeyAMapping, QuadFunction<A, B, C, D, GroupKeyB_> groupKeyBMapping,
QuadConstraintCollector<A, B, C, D, ResultContainer_, Result_> collector);
/**
* Combines the semantics of {@link #groupBy(QuadFunction, QuadFunction)} and
* {@link #groupBy(QuadConstraintCollector)}.
* That is, the first and second facts in the tuple follow the {@link #groupBy(QuadFunction, QuadFunction)}
* semantics.
* The third fact is the result of applying the first {@link QuadConstraintCollector#finisher()} on all the tuples
* of the original {@link QuadConstraintStream} that belong to the group.
* The fourth fact is the result of applying the second {@link QuadConstraintCollector#finisher()} on all the tuples
* of the original {@link QuadConstraintStream} that belong to the group
*
* @param groupKeyAMapping never null, function to convert the original tuple into a first fact
* @param groupKeyBMapping never null, function to convert the original tuple into a second fact
* @param collectorC never null, the collector to perform the first grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param collectorD never null, the collector to perform the second grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param <GroupKeyA_> the type of the first fact in the destination {@link QuadConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @param <GroupKeyB_> the type of the second fact in the destination {@link QuadConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @param <ResultContainerC_> the mutable accumulation type (often hidden as an implementation detail)
* @param <ResultC_> the type of the third fact in the destination {@link QuadConstraintStream}'s tuple
* @param <ResultContainerD_> the mutable accumulation type (often hidden as an implementation detail)
* @param <ResultD_> the type of the fourth fact in the destination {@link QuadConstraintStream}'s tuple
* @return never null
*/
<GroupKeyA_, GroupKeyB_, ResultContainerC_, ResultC_, ResultContainerD_, ResultD_>
QuadConstraintStream<GroupKeyA_, GroupKeyB_, ResultC_, ResultD_> groupBy(
QuadFunction<A, B, C, D, GroupKeyA_> groupKeyAMapping,
QuadFunction<A, B, C, D, GroupKeyB_> groupKeyBMapping,
QuadConstraintCollector<A, B, C, D, ResultContainerC_, ResultC_> collectorC,
QuadConstraintCollector<A, B, C, D, ResultContainerD_, ResultD_> collectorD);
/**
* Convert the {@link QuadConstraintStream} to a {@link TriConstraintStream}, consisting of unique tuples with three
* facts.
* <p>
* The first fact is the return value of the first group key mapping function, applied on the incoming tuple.
* The second fact is the return value of the second group key mapping function, applied on all incoming tuples with
* the same first fact.
* The third fact is the return value of the third group key mapping function, applied on all incoming tuples with
* the same first fact.
*
* @param groupKeyAMapping never null, function to convert the original tuple into a first fact
* @param groupKeyBMapping never null, function to convert the original tuple into a second fact
* @param groupKeyCMapping never null, function to convert the original tuple into a third fact
* @param <GroupKeyA_> the type of the first fact in the destination {@link TriConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @param <GroupKeyB_> the type of the second fact in the destination {@link TriConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @param <GroupKeyC_> the type of the third fact in the destination {@link TriConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @return never null
*/
<GroupKeyA_, GroupKeyB_, GroupKeyC_> TriConstraintStream<GroupKeyA_, GroupKeyB_, GroupKeyC_> groupBy(
QuadFunction<A, B, C, D, GroupKeyA_> groupKeyAMapping,
QuadFunction<A, B, C, D, GroupKeyB_> groupKeyBMapping,
QuadFunction<A, B, C, D, GroupKeyC_> groupKeyCMapping);
/**
* Combines the semantics of {@link #groupBy(QuadFunction, QuadFunction)} and {@link #groupBy(QuadConstraintCollector)}.
* That is, the first three facts in the tuple follow the {@link #groupBy(QuadFunction, QuadFunction)} semantics.
* The final fact is the result of applying the first {@link QuadConstraintCollector#finisher()} on all the tuples
* of the original {@link QuadConstraintStream} that belong to the group.
*
* @param groupKeyAMapping never null, function to convert the original tuple into a first fact
* @param groupKeyBMapping never null, function to convert the original tuple into a second fact
* @param groupKeyCMapping never null, function to convert the original tuple into a third fact
* @param collectorD never null, the collector to perform the grouping operation with
* See {@link ConstraintCollectors} for common operations, such as {@code count()}, {@code sum()} and others.
* @param <GroupKeyA_> the type of the first fact in the destination {@link QuadConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @param <GroupKeyB_> the type of the second fact in the destination {@link QuadConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @param <GroupKeyC_> the type of the third fact in the destination {@link QuadConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @param <ResultContainerD_> the mutable accumulation type (often hidden as an implementation detail)
* @param <ResultD_> the type of the fourth fact in the destination {@link QuadConstraintStream}'s tuple
* @return never null
*/
<GroupKeyA_, GroupKeyB_, GroupKeyC_, ResultContainerD_, ResultD_>
QuadConstraintStream<GroupKeyA_, GroupKeyB_, GroupKeyC_, ResultD_> groupBy(
QuadFunction<A, B, C, D, GroupKeyA_> groupKeyAMapping,
QuadFunction<A, B, C, D, GroupKeyB_> groupKeyBMapping,
QuadFunction<A, B, C, D, GroupKeyC_> groupKeyCMapping,
QuadConstraintCollector<A, B, C, D, ResultContainerD_, ResultD_> collectorD);
/**
* Convert the {@link TriConstraintStream} to a {@link QuadConstraintStream}, consisting of unique tuples with four
* facts.
* <p>
* The first fact is the return value of the first group key mapping function, applied on the incoming tuple.
* The second fact is the return value of the second group key mapping function, applied on all incoming tuples with
* the same first fact.
* The third fact is the return value of the third group key mapping function, applied on all incoming tuples with
* the same first fact.
* The fourth fact is the return value of the fourth group key mapping function, applied on all incoming tuples with
* the same first fact.
*
* @param groupKeyAMapping never null, function to convert the original tuple into a first fact
* @param groupKeyBMapping never null, function to convert the original tuple into a second fact
* @param groupKeyCMapping never null, function to convert the original tuple into a third fact
* @param groupKeyDMapping never null, function to convert the original tuple into a fourth fact
* @param <GroupKeyA_> the type of the first fact in the destination {@link QuadConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @param <GroupKeyB_> the type of the second fact in the destination {@link QuadConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @param <GroupKeyC_> the type of the third fact in the destination {@link QuadConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @param <GroupKeyD_> the type of the fourth fact in the destination {@link QuadConstraintStream}'s tuple;
* must honor {@link Object#hashCode() the general contract of hashCode}.
* @return never null
*/
<GroupKeyA_, GroupKeyB_, GroupKeyC_, GroupKeyD_>
QuadConstraintStream<GroupKeyA_, GroupKeyB_, GroupKeyC_, GroupKeyD_> groupBy(
QuadFunction<A, B, C, D, GroupKeyA_> groupKeyAMapping,
QuadFunction<A, B, C, D, GroupKeyB_> groupKeyBMapping,
QuadFunction<A, B, C, D, GroupKeyC_> groupKeyCMapping,
QuadFunction<A, B, C, D, GroupKeyD_> groupKeyDMapping);
// ************************************************************************
// Operations with duplicate tuple possibility
// ************************************************************************
/**
* As defined by {@link UniConstraintStream#map(Function)}.
*
* @param mapping never null, function to convert the original tuple into the new tuple
* @param <ResultA_> the type of the only fact in the resulting {@link UniConstraintStream}'s tuple
* @return never null
*/
<ResultA_> UniConstraintStream<ResultA_> map(QuadFunction<A, B, C, D, ResultA_> mapping);
/**
* As defined by {@link BiConstraintStream#flattenLast(Function)}.
*
* @param <ResultD_> the type of the last fact in the resulting tuples.
* It is recommended that this type be deeply immutable.
* Not following this recommendation may lead to hard-to-debug hashing issues down the stream,
* especially if this value is ever used as a group key.
* @param mapping never null, function to convert the last fact in the original tuple into {@link Iterable}
* @return never null
*/
<ResultD_> QuadConstraintStream<A, B, C, ResultD_> flattenLast(Function<D, Iterable<ResultD_>> mapping);
/**
* Transforms the stream in such a way that all the tuples going through it are distinct.
* (No two tuples will {@link Object#equals(Object) equal}.)
*
* <p>
* By default, tuples going through a constraint stream are distinct.
* However, operations such as {@link #map(QuadFunction)} may create a stream which breaks that promise.
* By calling this method on such a stream,
* duplicate copies of the same tuple will be omitted at a performance cost.
*
* @return never null
*/
QuadConstraintStream<A, B, C, D> distinct();
// ************************************************************************
// Penalize/reward
// ************************************************************************
/**
* As defined by {@link #penalize(Score, ToIntQuadFunction)}, where the match weight is one (1).
*
* @return never null
*/
default <Score_ extends Score<Score_>> QuadConstraintBuilder<A, B, C, D, Score_> penalize(Score_ constraintWeight) {
return penalize(constraintWeight, (a, b, c, d) -> 1);
}