mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-22 13:10:59 +00:00
Implement GSCSConstraint and suppoorting classes
This commit is contained in:
parent
2be7334ce2
commit
bddf6cfd03
11 changed files with 1256 additions and 27 deletions
|
@ -364,6 +364,8 @@ GSCSConstraint.m \
|
|||
GSCSVariable.m \
|
||||
GSCSSolution.m \
|
||||
GSCSFloatComparator.m \
|
||||
GSCSLinearExpression.m \
|
||||
GSCSStrength.m
|
||||
|
||||
# Turn off NSMenuItem warning that NSMenuItem conforms to <NSObject>,
|
||||
# but does not implement <NSObject>'s methods itself (it inherits
|
||||
|
@ -684,8 +686,11 @@ GSAutoLayoutEngine.h \
|
|||
GSCassowarySolver.h \
|
||||
GSCSConstraint.h \
|
||||
GSCSVariable.h \
|
||||
GSCSFloatComparator.h \
|
||||
GSCSSolution.h \
|
||||
GSCSFloatComparator.h
|
||||
GSCSLinearExpression.h \
|
||||
GSCSConstraintOperator.h \
|
||||
GSCSStrength.h
|
||||
|
||||
libgnustep-gui_HEADER_FILES = ${GUI_HEADERS}
|
||||
|
||||
|
|
|
@ -1,31 +1,124 @@
|
|||
/* Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
|
||||
By: Benjamin Johnson
|
||||
Date: 19-3-2023
|
||||
This file is part of the GNUstep Library.
|
||||
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110 USA.
|
||||
*/
|
||||
|
||||
#import "GSCSConstraintOperator.h"
|
||||
#import "GSCSLinearExpression.h"
|
||||
#import "GSCSStrength.h"
|
||||
#import "GSCSVariable.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#ifndef _GS_CS_CONSTRAINT_H
|
||||
#define _GS_CS_CONSTRAINT_H
|
||||
|
||||
enum GSCSConstraintType
|
||||
{
|
||||
GSCSConstraintTypeEdit,
|
||||
GSCSConstraintTypeStay,
|
||||
GSCSConstraintTypeLinear,
|
||||
GSCSConstraintTypeLinearInequity
|
||||
};
|
||||
typedef enum GSCSConstraintType GSCSConstraintType;
|
||||
|
||||
@interface GSCSConstraint : NSObject
|
||||
{
|
||||
GSCSConstraintType _type;
|
||||
GSCSStrength *_strength;
|
||||
GSCSLinearExpression *_expression;
|
||||
GSCSVariable *_variable;
|
||||
}
|
||||
|
||||
- (instancetype) initWithType: (GSCSConstraintType)type
|
||||
strength: (GSCSStrength *)strength
|
||||
expression: (GSCSLinearExpression *)expression
|
||||
variable: (GSCSVariable *)variable;
|
||||
|
||||
- (instancetype) initLinearConstraintWithExpression:
|
||||
(GSCSLinearExpression *)expression;
|
||||
|
||||
- (instancetype) initLinearInequityConstraintWithExpression:
|
||||
(GSCSLinearExpression *)expression;
|
||||
|
||||
- (instancetype) initLinearConstraintWithExpression:
|
||||
(GSCSLinearExpression *)expression
|
||||
strength: (GSCSStrength *)strength
|
||||
variable: (GSCSVariable *)variable;
|
||||
|
||||
- (instancetype) initEditConstraintWithVariable: (GSCSVariable *)variable
|
||||
stength: (GSCSStrength *)strength;
|
||||
|
||||
- (instancetype) initStayConstraintWithVariable: (GSCSVariable *)variable
|
||||
strength: (GSCSStrength *)strength;
|
||||
|
||||
- (instancetype) initWithLhsVariable: (GSCSVariable *)lhs
|
||||
equalsConstant: (CGFloat)rhs;
|
||||
|
||||
- (instancetype) initWithLhsVariable: (GSCSVariable *)lhs
|
||||
equalsRhsVariable: (GSCSVariable *)rhs;
|
||||
|
||||
+ (GSCSConstraint *) constraintWithLeftVariable: (GSCSVariable *)lhs
|
||||
operator: (GSCSConstraintOperator) operator
|
||||
rightVariable: (GSCSVariable *)rhsVariable;
|
||||
|
||||
+ (GSCSConstraint *) constraintWithLeftVariable: (GSCSVariable *)lhs
|
||||
operator: (GSCSConstraintOperator) operator
|
||||
rightConstant: (CGFloat)rhs;
|
||||
|
||||
+ (GSCSConstraint *) constraintWithLeftVariable: (GSCSVariable *)lhs
|
||||
operator: (GSCSConstraintOperator) operator
|
||||
rightExpression: (GSCSLinearExpression *)rhs;
|
||||
|
||||
+ (GSCSConstraint *) constraintWithLeftConstant: (CGFloat)lhs
|
||||
operator: (GSCSConstraintOperator) operator
|
||||
rightVariable: (GSCSVariable *)rhs;
|
||||
|
||||
+ (GSCSConstraint *) constraintWithLeftExpression: (GSCSLinearExpression *)lhs
|
||||
operator: (GSCSConstraintOperator) operator
|
||||
rightVariable: (GSCSVariable *)rhs;
|
||||
|
||||
+ (GSCSConstraint *) constraintWithLeftExpression: (GSCSLinearExpression *)lhs
|
||||
operator: (GSCSConstraintOperator) operator
|
||||
rightExpression: (GSCSLinearExpression *)rhs;
|
||||
|
||||
+ (GSCSConstraint *) constraintWithLeftExpression: (GSCSLinearExpression *)lhs
|
||||
operator: (GSCSConstraintOperator) operator
|
||||
rightConstant: (CGFloat)rhs;
|
||||
|
||||
+ (instancetype) editConstraintWithVariable: (GSCSVariable *)variable;
|
||||
|
||||
- (BOOL) isRequired;
|
||||
|
||||
- (BOOL) isEditConstraint;
|
||||
|
||||
- (BOOL) isStayConstraint;
|
||||
|
||||
- (BOOL) isInequality;
|
||||
|
||||
- (GSCSLinearExpression *) expression;
|
||||
|
||||
- (GSCSConstraintType) type;
|
||||
|
||||
- (GSCSStrength *) strength;
|
||||
|
||||
- (GSCSVariable *) variable;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/* Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
|
||||
By: Benjamin Johnson
|
||||
Date: 19-3-2023
|
||||
This file is part of the GNUstep Library.
|
||||
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
|
@ -21,7 +21,346 @@
|
|||
*/
|
||||
|
||||
#import "GSCSConstraint.h"
|
||||
#import "GSCSFloatComparator.h"
|
||||
#import "GSCSVariable.h"
|
||||
|
||||
@implementation GSCSConstraint
|
||||
|
||||
- (instancetype) init
|
||||
{
|
||||
return [self initWithType: GSCSConstraintTypeLinear
|
||||
strength: nil
|
||||
expression: nil
|
||||
variable: nil];
|
||||
}
|
||||
|
||||
- (instancetype) initWithType: (GSCSConstraintType)type
|
||||
strength: (GSCSStrength *)strength
|
||||
expression: (GSCSLinearExpression *)expression
|
||||
variable: (GSCSVariable *)variable
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
ASSIGN(_strength, strength != nil ? [strength copy]
|
||||
: [GSCSStrength strengthRequired]);
|
||||
ASSIGN(_expression, expression);
|
||||
ASSIGN(_variable, variable);
|
||||
_type = type;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype) initLinearConstraintWithExpression:
|
||||
(GSCSLinearExpression *)expression
|
||||
strength: (GSCSStrength *)strength
|
||||
variable: (GSCSVariable *)variable
|
||||
{
|
||||
return [self initWithType: GSCSConstraintTypeLinear
|
||||
strength: strength
|
||||
expression: expression
|
||||
variable: variable];
|
||||
}
|
||||
|
||||
- (instancetype) initLinearConstraintWithExpression:
|
||||
(GSCSLinearExpression *)expression
|
||||
{
|
||||
return
|
||||
[self initLinearConstraintWithExpression: expression
|
||||
strength: [GSCSStrength strengthRequired]
|
||||
variable: nil];
|
||||
}
|
||||
|
||||
- (instancetype) initLinearInequityConstraintWithExpression:
|
||||
(GSCSLinearExpression *)expression
|
||||
{
|
||||
return
|
||||
[self initWithType: GSCSConstraintTypeLinearInequity
|
||||
strength: [GSCSStrength strengthRequired]
|
||||
expression: expression
|
||||
variable: nil];
|
||||
}
|
||||
|
||||
- (instancetype) initEditConstraintWithVariable: (GSCSVariable *)variable
|
||||
stength: (GSCSStrength *)strength
|
||||
{
|
||||
GSCSLinearExpression *expression =
|
||||
[[GSCSLinearExpression alloc] initWithVariable: variable
|
||||
coefficient: -1
|
||||
constant: [variable value]];
|
||||
GSCSConstraint *constraint = [self initWithType: GSCSConstraintTypeEdit
|
||||
strength: strength
|
||||
expression: expression
|
||||
variable: variable];
|
||||
RELEASE(expression);
|
||||
return constraint;
|
||||
}
|
||||
|
||||
- (instancetype) initStayConstraintWithVariable: (GSCSVariable *)variable
|
||||
strength: (GSCSStrength *)strength
|
||||
{
|
||||
GSCSLinearExpression *expression =
|
||||
[[GSCSLinearExpression alloc] initWithVariable: variable
|
||||
coefficient: -1
|
||||
constant: [variable value]];
|
||||
GSCSConstraint *constraint = [[GSCSConstraint alloc] initWithType: GSCSConstraintTypeStay
|
||||
strength: strength
|
||||
expression: expression
|
||||
variable: variable];
|
||||
RELEASE(expression);
|
||||
return constraint;
|
||||
}
|
||||
|
||||
- (instancetype) initWithLhsVariable: (GSCSVariable *)lhs
|
||||
equalsRhsVariable: (GSCSVariable *)rhs
|
||||
{
|
||||
GSCSLinearExpression *expression =
|
||||
[[GSCSLinearExpression alloc] initWithVariable: lhs];
|
||||
[expression addVariable: rhs coefficient: -1];
|
||||
GSCSConstraint *constraint = [self initLinearConstraintWithExpression: expression];
|
||||
RELEASE(expression);
|
||||
|
||||
return constraint;
|
||||
}
|
||||
|
||||
- (instancetype) initWithLhsVariable: (GSCSVariable *)lhs
|
||||
equalsConstant: (CGFloat)rhs
|
||||
{
|
||||
GSCSLinearExpression *expression =
|
||||
[[GSCSLinearExpression alloc] initWithVariable: lhs
|
||||
coefficient: 1
|
||||
constant: -rhs];
|
||||
GSCSConstraint *constraint = [self initLinearConstraintWithExpression: expression];
|
||||
RELEASE(expression);
|
||||
return constraint;
|
||||
}
|
||||
|
||||
+ (GSCSConstraint *) constraintWithLeftVariable: (GSCSVariable *)lhs
|
||||
operator: (GSCSConstraintOperator) operator
|
||||
rightVariable: (GSCSVariable *)rhsVariable
|
||||
{
|
||||
if (operator== GSCSConstraintOperatorEqual)
|
||||
{
|
||||
GSCSLinearExpression *expression =
|
||||
[[GSCSLinearExpression alloc] initWithVariable: lhs];
|
||||
[expression addVariable: rhsVariable coefficient: -1];
|
||||
|
||||
RELEASE(expression);
|
||||
|
||||
return AUTORELEASE([[GSCSConstraint alloc]
|
||||
initLinearConstraintWithExpression: expression]);
|
||||
}
|
||||
else
|
||||
{
|
||||
GSCSLinearExpression *rhsExpression =
|
||||
[[GSCSLinearExpression alloc] initWithVariable: rhsVariable];
|
||||
if (operator== GSCSConstraintOperationGreaterThanOrEqual)
|
||||
{
|
||||
[rhsExpression multiplyConstantAndTermsBy: -1];
|
||||
[rhsExpression addVariable: lhs];
|
||||
}
|
||||
else if (operator== GSCSConstraintOperatorLessThanOrEqual)
|
||||
{
|
||||
[rhsExpression addVariable: lhs coefficient: -1];
|
||||
}
|
||||
|
||||
RELEASE(rhsExpression);
|
||||
|
||||
return AUTORELEASE([[GSCSConstraint alloc]
|
||||
initLinearInequityConstraintWithExpression: rhsExpression]);
|
||||
}
|
||||
}
|
||||
|
||||
+ (GSCSConstraint *) constraintWithLeftVariable: (GSCSVariable *)lhs
|
||||
operator: (GSCSConstraintOperator) operator
|
||||
rightConstant: (CGFloat)rhs
|
||||
{
|
||||
GSCSLinearExpression *expression;
|
||||
GSCSConstraint *constraint;
|
||||
if (operator== GSCSConstraintOperatorEqual)
|
||||
{
|
||||
expression = [[GSCSLinearExpression alloc] init];
|
||||
[expression addVariable: lhs coefficient: 1];
|
||||
[expression setConstant: -rhs];
|
||||
|
||||
constraint = [[GSCSConstraint alloc]
|
||||
initLinearConstraintWithExpression: expression
|
||||
strength: [GSCSStrength strengthRequired]
|
||||
variable: nil];
|
||||
}
|
||||
else
|
||||
{
|
||||
expression =
|
||||
[[GSCSLinearExpression alloc] initWithConstant: rhs];
|
||||
if (operator== GSCSConstraintOperationGreaterThanOrEqual)
|
||||
{
|
||||
[expression multiplyConstantAndTermsBy: -1];
|
||||
[expression addVariable: lhs coefficient: 1.0];
|
||||
}
|
||||
else if (operator== GSCSConstraintOperatorLessThanOrEqual)
|
||||
{
|
||||
[expression addVariable: lhs coefficient: -1.0];
|
||||
}
|
||||
|
||||
constraint = [[GSCSConstraint alloc]
|
||||
initLinearInequityConstraintWithExpression: expression];
|
||||
}
|
||||
|
||||
RELEASE(expression);
|
||||
return AUTORELEASE(constraint);
|
||||
}
|
||||
|
||||
+ (GSCSConstraint *) constraintWithLeftVariable: (GSCSVariable *)lhs
|
||||
operator: (GSCSConstraintOperator) operator
|
||||
rightExpression: (GSCSLinearExpression *)rhs
|
||||
{
|
||||
GSCSLinearExpression *lhsExpression =
|
||||
[[GSCSLinearExpression alloc] initWithVariable: lhs];
|
||||
GSCSConstraint *constraint = [self constraintWithLeftExpression:lhsExpression operator:operator rightExpression:rhs];
|
||||
RELEASE(lhsExpression);
|
||||
return constraint;
|
||||
}
|
||||
|
||||
+ (GSCSConstraint *) constraintWithLeftConstant: (CGFloat)lhs
|
||||
operator: (GSCSConstraintOperator) operator
|
||||
rightVariable: (GSCSVariable *)rhs
|
||||
{
|
||||
GSCSLinearExpression *valueExpression =
|
||||
[[GSCSLinearExpression alloc] initWithConstant: lhs];
|
||||
|
||||
GSCSConstraint *constraint = nil;
|
||||
if (operator== GSCSConstraintOperatorEqual)
|
||||
{
|
||||
[valueExpression addVariable: rhs coefficient: -1.0];
|
||||
constraint = [[GSCSConstraint alloc]
|
||||
initLinearConstraintWithExpression: valueExpression];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (operator== GSCSConstraintOperationGreaterThanOrEqual)
|
||||
{
|
||||
[valueExpression addVariable: rhs coefficient: -1.0];
|
||||
}
|
||||
else if (operator== GSCSConstraintOperatorLessThanOrEqual)
|
||||
{
|
||||
[valueExpression multiplyConstantAndTermsBy: -1];
|
||||
[valueExpression addVariable: rhs coefficient: 1.0];
|
||||
}
|
||||
|
||||
constraint = [[GSCSConstraint alloc]
|
||||
initLinearInequityConstraintWithExpression: valueExpression];
|
||||
}
|
||||
|
||||
RELEASE(valueExpression);
|
||||
return constraint;
|
||||
}
|
||||
|
||||
+ (GSCSConstraint *) constraintWithLeftExpression: (GSCSLinearExpression *)lhs
|
||||
operator: (GSCSConstraintOperator) operator
|
||||
rightVariable: (GSCSVariable *)rhs
|
||||
{
|
||||
GSCSLinearExpression *rhsExpression =
|
||||
[[GSCSLinearExpression alloc] initWithVariable: rhs];
|
||||
return [self constraintWithLeftExpression:lhs operator:operator rightExpression:rhsExpression];
|
||||
}
|
||||
|
||||
+ (GSCSConstraint *) constraintWithLeftExpression: (GSCSLinearExpression *)lhs
|
||||
operator: (GSCSConstraintOperator) operator
|
||||
rightExpression: (GSCSLinearExpression *)rhs
|
||||
{
|
||||
GSCSLinearExpression *expression = [rhs copy];
|
||||
GSCSConstraint *constraint;
|
||||
if (operator== GSCSConstraintOperatorEqual)
|
||||
{
|
||||
[expression addExpression: lhs multiplier: -1];
|
||||
constraint = [[GSCSConstraint alloc]
|
||||
initLinearConstraintWithExpression: expression];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (operator== GSCSConstraintOperationGreaterThanOrEqual)
|
||||
{
|
||||
[expression multiplyConstantAndTermsBy: -1];
|
||||
[expression addExpression: lhs];
|
||||
}
|
||||
else if (operator== GSCSConstraintOperatorLessThanOrEqual)
|
||||
{
|
||||
[expression addExpression: lhs multiplier: -1];
|
||||
}
|
||||
|
||||
constraint = [[GSCSConstraint alloc]
|
||||
initLinearInequityConstraintWithExpression: expression];
|
||||
}
|
||||
|
||||
RELEASE(expression);
|
||||
return AUTORELEASE(constraint);
|
||||
}
|
||||
|
||||
+ (GSCSConstraint *) constraintWithLeftExpression: (GSCSLinearExpression *)lhs
|
||||
operator: (GSCSConstraintOperator) operator
|
||||
rightConstant: (CGFloat)rhs
|
||||
{
|
||||
GSCSLinearExpression *rhsExpression =
|
||||
[[GSCSLinearExpression alloc] initWithConstant: rhs];
|
||||
GSCSConstraint *constraint = [self constraintWithLeftExpression:lhs operator:operator rightExpression:rhsExpression];
|
||||
RELEASE(rhsExpression);
|
||||
return constraint;
|
||||
}
|
||||
|
||||
+ (instancetype) editConstraintWithVariable: (GSCSVariable *)variable
|
||||
{
|
||||
return AUTORELEASE([[self alloc]
|
||||
initEditConstraintWithVariable: variable
|
||||
stength: [GSCSStrength strengthStrong]]);
|
||||
}
|
||||
|
||||
- (BOOL) isRequired
|
||||
{
|
||||
return [_strength isRequired];
|
||||
}
|
||||
|
||||
- (BOOL) isEditConstraint
|
||||
{
|
||||
return _type == GSCSConstraintTypeEdit;
|
||||
}
|
||||
|
||||
- (BOOL) isStayConstraint
|
||||
{
|
||||
return _type == GSCSConstraintTypeStay;
|
||||
}
|
||||
|
||||
- (BOOL) isInequality
|
||||
{
|
||||
return _type == GSCSConstraintTypeLinearInequity;
|
||||
}
|
||||
|
||||
- (GSCSLinearExpression *) expression
|
||||
{
|
||||
return _expression;
|
||||
}
|
||||
|
||||
- (GSCSVariable *) variable
|
||||
{
|
||||
return _variable;
|
||||
}
|
||||
|
||||
- (GSCSStrength *) strength
|
||||
{
|
||||
return _strength;
|
||||
}
|
||||
|
||||
- (GSCSConstraintType) type
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(_strength);
|
||||
RELEASE(_expression);
|
||||
RELEASE(_variable);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
34
Source/GSCSConstraintOperator.h
Normal file
34
Source/GSCSConstraintOperator.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
By: Benjamin Johnson
|
||||
Date: 19-3-2023
|
||||
This file is part of the GNUstep Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110 USA.
|
||||
*/
|
||||
|
||||
#ifndef GSCSConstraintOperator_h
|
||||
#define GSCSConstraintOperator_h
|
||||
|
||||
enum GSCSConstraintOperator
|
||||
{
|
||||
GSCSConstraintOperatorEqual,
|
||||
GSCSConstraintOperationGreaterThanOrEqual,
|
||||
GSCSConstraintOperatorLessThanOrEqual,
|
||||
};
|
||||
typedef enum GSCSConstraintOperator GSCSConstraintOperator;
|
||||
|
||||
#endif /* GSCSConstraintOperator_h */
|
92
Source/GSCSLinearExpression.h
Normal file
92
Source/GSCSLinearExpression.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
/* Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
By: Benjamin Johnson
|
||||
Date: 19-3-2023
|
||||
This file is part of the GNUstep Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110 USA.
|
||||
*/
|
||||
|
||||
#import "GSCSVariable.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#ifndef _GS_CS_LINEAR_EXPRESSION_H
|
||||
#define _GS_CS_LINEAR_EXPRESSION_H
|
||||
|
||||
@interface GSCSLinearExpression : NSObject <NSCopying>
|
||||
{
|
||||
NSMapTable *_terms;
|
||||
CGFloat _constant;
|
||||
NSMutableArray *_termVariables;
|
||||
}
|
||||
|
||||
- (instancetype) initWithConstant: (CGFloat)constant;
|
||||
|
||||
- (instancetype) initWithVariable: (GSCSVariable *)variable;
|
||||
|
||||
- (instancetype) initWithVariable: (GSCSVariable *)variable
|
||||
coefficient: (CGFloat)value
|
||||
constant: (CGFloat)constant;
|
||||
|
||||
- (instancetype) initWithVariables: (NSArray *)variables;
|
||||
|
||||
- (CGFloat) constant;
|
||||
|
||||
- (void) setConstant: (CGFloat)constant;
|
||||
|
||||
- (NSMapTable *) terms;
|
||||
|
||||
- (NSArray *) termVariables;
|
||||
|
||||
- (NSNumber *) multiplierForTerm: (GSCSVariable *)variable;
|
||||
|
||||
- (void) removeVariable: (GSCSVariable *)variable;
|
||||
|
||||
- (void) multiplyConstantAndTermsBy: (CGFloat)value;
|
||||
|
||||
- (void) divideConstantAndTermsBy: (CGFloat)value;
|
||||
|
||||
- (CGFloat) coefficientForTerm: (GSCSVariable *)variable;
|
||||
|
||||
- (CGFloat) newSubject: (GSCSVariable *)subject;
|
||||
|
||||
- (void) addVariable: (GSCSVariable *)variable;
|
||||
|
||||
- (void) addVariable: (GSCSVariable *)variable
|
||||
coefficient: (CGFloat)coefficient;
|
||||
|
||||
- (void) addExpression: (GSCSLinearExpression *)expression;
|
||||
|
||||
- (void) addExpression: (GSCSLinearExpression *)expression
|
||||
multiplier: (CGFloat)multiplier;
|
||||
|
||||
- (NSArray *) findPivotableVariablesWithMostNegativeCoefficient;
|
||||
|
||||
- (void) normalize;
|
||||
|
||||
- (BOOL) isConstant;
|
||||
|
||||
- (BOOL) isTermForVariable: (GSCSVariable *)variable;
|
||||
|
||||
- (GSCSVariable *) anyPivotableVariable;
|
||||
|
||||
- (NSArray *) externalVariables;
|
||||
|
||||
- (BOOL) containsOnlyDummyVariables;
|
||||
|
||||
@end
|
||||
|
||||
#endif //_GS_CS_LINEAR_EXPRESSION_H
|
317
Source/GSCSLinearExpression.m
Normal file
317
Source/GSCSLinearExpression.m
Normal file
|
@ -0,0 +1,317 @@
|
|||
/* Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
By: Benjamin Johnson
|
||||
Date: 19-3-2023
|
||||
This file is part of the GNUstep Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110 USA.
|
||||
*/
|
||||
|
||||
#import "GSCSLinearExpression.h"
|
||||
#import "GSCSFloatComparator.h"
|
||||
#import "GSCSVariable.h"
|
||||
#import "GSFastEnumeration.h"
|
||||
|
||||
@implementation GSCSLinearExpression
|
||||
|
||||
- (instancetype) init
|
||||
{
|
||||
self = [super init];
|
||||
if (self)
|
||||
{
|
||||
ASSIGN(_terms, [NSMapTable strongToStrongObjectsMapTable]);
|
||||
ASSIGN(_termVariables, [NSMutableArray array]);
|
||||
_constant = 0;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype) initWithVariable: (GSCSVariable *)variable
|
||||
{
|
||||
self = [self init];
|
||||
if (self)
|
||||
{
|
||||
[self addVariable: variable coefficient: 1.0];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype) initWithVariables: (NSArray *)variables
|
||||
{
|
||||
self = [self init];
|
||||
if (self)
|
||||
{
|
||||
FOR_IN(GSCSVariable *, variable, variables)
|
||||
[self addVariable: variable coefficient: 1.0];
|
||||
END_FOR_IN(variables)
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype) initWithConstant: (CGFloat)constant
|
||||
{
|
||||
self = [self init];
|
||||
if (self)
|
||||
{
|
||||
_constant = constant;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype) initWithVariable: (GSCSVariable *)variable
|
||||
coefficient: (CGFloat)coefficient
|
||||
constant: (CGFloat)constant
|
||||
{
|
||||
self = [self init];
|
||||
if (self)
|
||||
{
|
||||
[self addVariable: variable coefficient: coefficient];
|
||||
_constant = constant;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (CGFloat) constant
|
||||
{
|
||||
return _constant;
|
||||
}
|
||||
|
||||
- (void) setConstant: (CGFloat)constant
|
||||
{
|
||||
_constant = constant;
|
||||
}
|
||||
|
||||
- (NSMapTable *) terms
|
||||
{
|
||||
return _terms;
|
||||
}
|
||||
|
||||
- (NSArray *) termVariables
|
||||
{
|
||||
return _termVariables;
|
||||
}
|
||||
|
||||
- (void) removeVariable: (GSCSVariable *)variable
|
||||
{
|
||||
[_terms removeObjectForKey: variable];
|
||||
[_termVariables removeObject: variable];
|
||||
}
|
||||
|
||||
- (NSNumber *) multiplierForTerm: (GSCSVariable *)variable
|
||||
{
|
||||
return [_terms objectForKey: variable];
|
||||
}
|
||||
|
||||
- (CGFloat) newSubject: (GSCSVariable *)subject
|
||||
{
|
||||
CGFloat reciprocal = 1.0 / [self coefficientForTerm: subject];
|
||||
|
||||
[self multiplyConstantAndTermsBy:-reciprocal];
|
||||
|
||||
[self removeVariable: subject];
|
||||
return reciprocal;
|
||||
}
|
||||
|
||||
- (void) multiplyConstantAndTermsBy: (CGFloat)value
|
||||
{
|
||||
_constant = _constant * value;
|
||||
|
||||
NSMutableArray *keys = [NSMutableArray arrayWithCapacity: [_terms count]];
|
||||
FOR_IN(GSCSVariable *, term, _terms)
|
||||
[keys addObject: term];
|
||||
END_FOR_IN(_terms)
|
||||
|
||||
FOR_IN(GSCSVariable *, term, keys)
|
||||
NSNumber *termCoefficent = [_terms objectForKey: term];
|
||||
CGFloat multipliedTermCoefficent = [termCoefficent doubleValue] * value;
|
||||
[_terms setObject: [NSNumber numberWithDouble: multipliedTermCoefficent]
|
||||
forKey: term];
|
||||
END_FOR_IN(keys)
|
||||
}
|
||||
|
||||
- (void) divideConstantAndTermsBy: (CGFloat)value
|
||||
{
|
||||
[self multiplyConstantAndTermsBy: 1 / value];
|
||||
}
|
||||
|
||||
- (CGFloat) coefficientForTerm: (GSCSVariable *)variable
|
||||
{
|
||||
return [[self multiplierForTerm: variable] floatValue];
|
||||
}
|
||||
|
||||
- (void) normalize
|
||||
{
|
||||
[self multiplyConstantAndTermsBy:-1];
|
||||
}
|
||||
|
||||
- (id) copyWithZone: (NSZone *)zone
|
||||
{
|
||||
GSCSLinearExpression *expression = [[[self class] allocWithZone: zone] init];
|
||||
if (expression)
|
||||
{
|
||||
[expression setConstant: [self constant]];
|
||||
FOR_IN(GSCSVariable *, variable, _termVariables)
|
||||
[expression addVariable: variable
|
||||
coefficient: [self coefficientForTerm: variable]];
|
||||
END_FOR_IN(_termVariables)
|
||||
}
|
||||
|
||||
return expression;
|
||||
}
|
||||
|
||||
- (NSArray *) findPivotableVariablesWithMostNegativeCoefficient
|
||||
{
|
||||
CGFloat mostNegativeCoefficient = 0;
|
||||
FOR_IN(GSCSVariable *, term, _termVariables)
|
||||
CGFloat coefficientForTerm = [self coefficientForTerm: term];
|
||||
if ([term isPivotable] && coefficientForTerm < mostNegativeCoefficient)
|
||||
{
|
||||
mostNegativeCoefficient = coefficientForTerm;
|
||||
}
|
||||
END_FOR_IN(_termVariables)
|
||||
|
||||
NSMutableArray *candidates = [NSMutableArray array];
|
||||
FOR_IN(GSCSVariable *, term, _termVariables)
|
||||
CGFloat coefficientForTerm = [self coefficientForTerm: term];
|
||||
if ([term isPivotable] &&
|
||||
[GSCSFloatComparator isApproxiatelyEqual: coefficientForTerm
|
||||
b: mostNegativeCoefficient])
|
||||
{
|
||||
[candidates addObject: term];
|
||||
}
|
||||
END_FOR_IN(_termVariables)
|
||||
|
||||
return candidates;
|
||||
}
|
||||
|
||||
- (BOOL) isConstant
|
||||
{
|
||||
return [_terms count] == 0;
|
||||
}
|
||||
|
||||
- (BOOL) isTermForVariable: (GSCSVariable *)variable
|
||||
{
|
||||
return [_terms objectForKey: variable] != nil;
|
||||
}
|
||||
|
||||
- (GSCSVariable *) anyPivotableVariable
|
||||
{
|
||||
if ([self isConstant])
|
||||
{
|
||||
[[NSException exceptionWithName: NSInternalInconsistencyException
|
||||
reason: @"anyPivotableVariable invoked on a "
|
||||
@"constant expression"
|
||||
userInfo: nil] raise];
|
||||
}
|
||||
|
||||
FOR_IN(GSCSVariable *, variable, _termVariables)
|
||||
if ([variable isPivotable])
|
||||
{
|
||||
return variable;
|
||||
}
|
||||
END_FOR_IN(_termVariables)
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL) containsOnlyDummyVariables
|
||||
{
|
||||
FOR_IN(GSCSVariable *, term, _termVariables)
|
||||
if (![term isDummy])
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
END_FOR_IN(_termVariables)
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (NSArray *) externalVariables
|
||||
{
|
||||
NSMutableArray *externalVariables = [NSMutableArray array];
|
||||
FOR_IN(GSCSVariable *, variable, _terms)
|
||||
if ([variable isExternal])
|
||||
{
|
||||
[externalVariables addObject: variable];
|
||||
}
|
||||
END_FOR_IN(_terms)
|
||||
|
||||
return externalVariables;
|
||||
}
|
||||
|
||||
- (void) addVariable: (GSCSVariable *)variable
|
||||
{
|
||||
[self addVariable: variable coefficient: 1];
|
||||
}
|
||||
|
||||
- (void) addVariable: (GSCSVariable *)variable
|
||||
coefficient: (CGFloat)coefficient;
|
||||
{
|
||||
if (![GSCSFloatComparator isApproxiatelyZero: coefficient])
|
||||
{
|
||||
if ([self isTermForVariable: variable])
|
||||
{
|
||||
[_termVariables removeObject: variable];
|
||||
}
|
||||
[_terms setObject: [NSNumber numberWithFloat: coefficient]
|
||||
forKey: variable];
|
||||
[_termVariables addObject: variable];
|
||||
}
|
||||
}
|
||||
|
||||
- (NSString *) description
|
||||
{
|
||||
NSString *descriptionString = [NSString stringWithFormat:@"%f", _constant];
|
||||
FOR_IN(GSCSVariable *, term, _termVariables)
|
||||
descriptionString = [descriptionString
|
||||
stringByAppendingString:
|
||||
[NSString stringWithFormat: @" + %f * %@",
|
||||
[self coefficientForTerm: term],
|
||||
[term description]]];
|
||||
END_FOR_IN(_termVariables)
|
||||
|
||||
return descriptionString;
|
||||
}
|
||||
|
||||
- (void) addExpression: (GSCSLinearExpression *)expression
|
||||
{
|
||||
[self addExpression: expression multiplier: 1];
|
||||
}
|
||||
|
||||
- (void) addExpression: (GSCSLinearExpression *)expression
|
||||
multiplier: (CGFloat)multiplier
|
||||
{
|
||||
[self setConstant: [self constant] + expression.constant * multiplier];
|
||||
NSArray *termVariables = [expression termVariables];
|
||||
FOR_IN(GSCSVariable *, term, termVariables)
|
||||
CGFloat termCoefficient =
|
||||
[expression coefficientForTerm: term] * multiplier;
|
||||
[self addVariable: term coefficient: termCoefficient];
|
||||
END_FOR_IN(termVariables)
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(_terms);
|
||||
RELEASE(_termVariables);
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
|
@ -65,12 +65,13 @@
|
|||
NSNumber *rhsResult = [solution resultForVariable: variable];
|
||||
|
||||
BOOL hasResultForBoth = lhsResult != nil && rhsResult != nil;
|
||||
if (!hasResultForBoth) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (!hasResultForBoth)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
return [GSCSFloatComparator isApproxiatelyEqual: [lhsResult floatValue]
|
||||
b: [rhsResult floatValue]];
|
||||
b: [rhsResult floatValue]];
|
||||
}
|
||||
|
||||
- (BOOL) isEqualToCassowarySolverSolution: (GSCSSolution *)solution
|
||||
|
@ -91,10 +92,10 @@
|
|||
return YES;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE (_resultsByVariable);
|
||||
[super dealloc];
|
||||
}
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(_resultsByVariable);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
52
Source/GSCSStrength.h
Normal file
52
Source/GSCSStrength.h
Normal file
|
@ -0,0 +1,52 @@
|
|||
/* Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
By: Benjamin Johnson
|
||||
Date: 19-3-2023
|
||||
This file is part of the GNUstep Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110 USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#ifndef _GS_CS_STRENGTH_H
|
||||
#define _GS_CS_STRENGTH_H
|
||||
|
||||
@interface GSCSStrength : NSObject <NSCopying>
|
||||
{
|
||||
NSString *_name;
|
||||
double _strength;
|
||||
}
|
||||
|
||||
- (NSString *) name;
|
||||
|
||||
- (double) strength;
|
||||
|
||||
- (instancetype) initWithName: (NSString *)name strength: (double)strength;
|
||||
|
||||
+ (instancetype) strengthRequired;
|
||||
|
||||
+ (instancetype) strengthStrong;
|
||||
|
||||
+ (instancetype) strengthMedium;
|
||||
|
||||
+ (instancetype) strengthWeak;
|
||||
|
||||
- (BOOL) isRequired;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
112
Source/GSCSStrength.m
Normal file
112
Source/GSCSStrength.m
Normal file
|
@ -0,0 +1,112 @@
|
|||
/* Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
By: Benjamin Johnson
|
||||
Date: 19-3-2023
|
||||
This file is part of the GNUstep Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
Boston, MA 02110 USA.
|
||||
*/
|
||||
|
||||
#import "GSCSStrength.h"
|
||||
#import "GSCSFloatComparator.h"
|
||||
|
||||
@implementation GSCSStrength
|
||||
|
||||
- (instancetype) initWithName: (NSString *)name strength: (double)strength;
|
||||
{
|
||||
if (self = [super init])
|
||||
{
|
||||
ASSIGN(_name, name);
|
||||
_strength = strength;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (instancetype) strengthRequired
|
||||
{
|
||||
return AUTORELEASE([[GSCSStrength alloc] initWithName: @"<Required>" strength: 1000]);
|
||||
}
|
||||
|
||||
+ (instancetype) strengthStrong
|
||||
{
|
||||
return AUTORELEASE([[GSCSStrength alloc] initWithName: @"strong" strength: 750]);
|
||||
}
|
||||
|
||||
+ (instancetype) strengthMedium
|
||||
{
|
||||
return AUTORELEASE([[GSCSStrength alloc] initWithName: @"medium" strength: 500]);
|
||||
}
|
||||
|
||||
+ (instancetype) strengthWeak
|
||||
{
|
||||
return AUTORELEASE([[GSCSStrength alloc] initWithName: @"weak" strength: 250]);
|
||||
}
|
||||
|
||||
- (BOOL) isEqualToStrength: (GSCSStrength *)strength
|
||||
{
|
||||
return [_name isEqual: [strength name]] &&
|
||||
[GSCSFloatComparator isApproxiatelyEqual: _strength
|
||||
b: [strength strength]];
|
||||
}
|
||||
|
||||
- (BOOL) isEqual: (id)other
|
||||
{
|
||||
if (other == nil)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (other == self)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
|
||||
return [self isEqualToStrength: other];
|
||||
}
|
||||
|
||||
- (BOOL) isRequired
|
||||
{
|
||||
return [GSCSFloatComparator
|
||||
isApproxiatelyEqual: _strength
|
||||
b: [[GSCSStrength strengthRequired] strength]];
|
||||
}
|
||||
|
||||
- (double) strength
|
||||
{
|
||||
return _strength;
|
||||
}
|
||||
|
||||
- (NSString *) name
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
- (id) copyWithZone: (NSZone *)zone
|
||||
{
|
||||
GSCSStrength *copy =
|
||||
[[[self class] allocWithZone: zone] initWithName: _name
|
||||
strength: _strength];
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
RELEASE(_name);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
|
@ -1,19 +1,19 @@
|
|||
/* Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
|
||||
By: Benjamin Johnson
|
||||
Date: 19-3-2023
|
||||
This file is part of the GNUstep Library.
|
||||
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
|
@ -25,7 +25,49 @@
|
|||
#ifndef _GS_CS_VARIABLE_H
|
||||
#define _GS_CS_VARIABLE_H
|
||||
|
||||
enum GSCSVariableType
|
||||
{
|
||||
GSCSVariableTypeDummy,
|
||||
GSCSVariableTypeSlack,
|
||||
GSCSVaraibleTypeVariable,
|
||||
GSCSVariableTypeObjective,
|
||||
GSCSVariableTypeExternal
|
||||
};
|
||||
typedef enum GSCSVariableType GSCSVariableType;
|
||||
|
||||
@interface GSCSVariable : NSObject
|
||||
{
|
||||
GSCSVariableType _type;
|
||||
NSUInteger _id;
|
||||
CGFloat _value;
|
||||
NSString *_name;
|
||||
}
|
||||
|
||||
- (GSCSVariableType) type;
|
||||
|
||||
- (NSUInteger) id;
|
||||
|
||||
- (CGFloat) value;
|
||||
|
||||
- (void) setValue: (CGFloat)value;
|
||||
|
||||
- (NSString *) name;
|
||||
|
||||
- (BOOL) isExternal;
|
||||
|
||||
- (BOOL) isDummy;
|
||||
|
||||
- (BOOL) isPivotable;
|
||||
|
||||
- (BOOL) isRestricted;
|
||||
|
||||
- (instancetype) initWithName: (NSString *)name;
|
||||
|
||||
+ (instancetype) variable;
|
||||
|
||||
+ (instancetype) variableWithValue: (CGFloat)value;
|
||||
|
||||
+ (instancetype) variableWithValue: (CGFloat)value name: (NSString *)name;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
/* Copyright (C) 2023 Free Software Foundation, Inc.
|
||||
|
||||
|
||||
By: Benjamin Johnson
|
||||
Date: 19-3-2023
|
||||
This file is part of the GNUstep Library.
|
||||
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2.1 of the License, or (at your option) any later version.
|
||||
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
|
@ -24,4 +24,146 @@
|
|||
|
||||
@implementation GSCSVariable
|
||||
|
||||
- (instancetype) init
|
||||
{
|
||||
self = [super init];
|
||||
if (self != nil)
|
||||
{
|
||||
_type = GSCSVaraibleTypeVariable;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype) initWithName: (NSString *)name
|
||||
{
|
||||
self = [super init];
|
||||
if (self != nil)
|
||||
{
|
||||
ASSIGN(_name, name);
|
||||
_type = GSCSVaraibleTypeVariable;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype) initWithName: (NSString *)name type: (GSCSVariableType)type
|
||||
{
|
||||
self = [super init];
|
||||
if (self != nil)
|
||||
{
|
||||
ASSIGN(_name, name);
|
||||
_type = type;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (instancetype) dummyVariableWithName: (NSString *)name
|
||||
{
|
||||
return AUTORELEASE([[GSCSVariable alloc] initWithName: name type: GSCSVariableTypeDummy]);
|
||||
}
|
||||
|
||||
+ (instancetype) slackVariableWithName: (NSString *)name
|
||||
{
|
||||
return AUTORELEASE([[GSCSVariable alloc] initWithName: name type: GSCSVariableTypeSlack]);
|
||||
}
|
||||
|
||||
+ (instancetype) objectiveVariableWithName: (NSString *)name
|
||||
{
|
||||
return AUTORELEASE([[GSCSVariable alloc] initWithName: name
|
||||
type: GSCSVariableTypeObjective]);
|
||||
}
|
||||
|
||||
+ (instancetype) variableWithValue: (CGFloat)value
|
||||
{
|
||||
return [self variableWithValue: value name: nil];
|
||||
}
|
||||
|
||||
+ (instancetype) variable
|
||||
{
|
||||
return [self variableWithValue: 0 name: nil];
|
||||
}
|
||||
|
||||
+ (instancetype) variableWithValue: (CGFloat)value name: (NSString *)name
|
||||
{
|
||||
GSCSVariable *variable =
|
||||
[[GSCSVariable alloc] initWithName: name type: GSCSVariableTypeExternal];
|
||||
[variable setValue: value];
|
||||
return AUTORELEASE(variable);
|
||||
}
|
||||
|
||||
- (BOOL) isDummy
|
||||
{
|
||||
return _type == GSCSVariableTypeDummy;
|
||||
}
|
||||
|
||||
- (BOOL) isExternal
|
||||
{
|
||||
return _type == GSCSVariableTypeExternal;
|
||||
}
|
||||
|
||||
- (BOOL) isPivotable
|
||||
{
|
||||
return _type == GSCSVariableTypeSlack;
|
||||
}
|
||||
|
||||
- (BOOL) isRestricted
|
||||
{
|
||||
return _type == GSCSVariableTypeExternal || _type == GSCSVariableTypeSlack;
|
||||
}
|
||||
|
||||
- (NSString *) description
|
||||
{
|
||||
if (_type == GSCSVariableTypeDummy)
|
||||
{
|
||||
return [NSString stringWithFormat: @"[%@:dummy]", _name];
|
||||
}
|
||||
else if (_type == GSCSVariableTypeSlack)
|
||||
{
|
||||
return [NSString stringWithFormat: @"[%@:slack]", _name];
|
||||
}
|
||||
else if (_type == GSCSVariableTypeExternal)
|
||||
{
|
||||
return [NSString stringWithFormat: @"[%@:%.02f]", _name, _value];
|
||||
}
|
||||
else if (_type == GSCSVariableTypeObjective)
|
||||
{
|
||||
return [NSString stringWithFormat: @"[%@:objective]", _name];
|
||||
}
|
||||
|
||||
return [NSString stringWithFormat: @"[%@]", _name];
|
||||
}
|
||||
|
||||
- (GSCSVariableType) type
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
|
||||
- (NSUInteger) id
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
- (CGFloat) value
|
||||
{
|
||||
return _value;
|
||||
}
|
||||
|
||||
- (void) setValue: (CGFloat)value
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
- (NSString *) name
|
||||
{
|
||||
return _name;
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
TEST_RELEASE(_name);
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
@end
|
Loading…
Reference in a new issue