1 module cassowary.SymbolicWeight;
2 
3 import std.conv;
4 import std.algorithm;
5 import std.array;
6 
7 class ClSymbolicWeight
8 {
9 	this(int cLevels) pure @safe nothrow
10 	{
11 		_values = new double[cLevels];
12 	}
13 
14 	this(double w1, double w2, double w3) pure @safe nothrow
15 	{
16 		_values = [w1, w2, w3];
17 	}
18 
19 	this(immutable double[] weights) pure @safe nothrow
20 	{
21 		_values = weights;
22 	}
23 
24 	static immutable ClSymbolicWeight clsZero = new immutable ClSymbolicWeight(0.0, 0.0, 0.0);
25 
26 	ClSymbolicWeight times(double n) const
27 	{
28 		return new ClSymbolicWeight(_values.map!(a => a * n)().array().idup);
29 	}
30 
31 	ClSymbolicWeight divideBy(double n) const
32 	{
33 		return new ClSymbolicWeight(_values.map!(a => a / n)().array().idup);
34 	}
35 
36 	ClSymbolicWeight add(ClSymbolicWeight cl) const
37 	{
38 		auto newValues = _values.dup;
39 		for (int i = 0; i < _values.length; i++)
40 		{
41 			newValues[i] += cl._values[i];
42 		}
43 		return new ClSymbolicWeight(newValues.idup);
44 	}
45 
46 	ClSymbolicWeight subtract(ClSymbolicWeight cl) const
47 	{
48 		auto newValues = _values.dup;
49 		for (int i = 0; i < _values.length; i++)
50 		{
51 			newValues[i] -= cl._values[i];
52 		}
53 		return new ClSymbolicWeight(newValues.idup);
54 	}
55 
56 	bool lessThan(const ClSymbolicWeight cl) const pure
57 	{
58 		// assert cl.cLevels() == cLevels()
59 		for (int i = 0; i < _values.length; i++)
60 		{
61 			if (_values[i] < cl._values[i])
62 				return true;
63 			else if (_values[i] > cl._values[i])
64 				return false;
65 		}
66 		return false; // they are equal
67 	}
68 
69 	bool lessThanOrEqual(ClSymbolicWeight cl) const pure
70 	{
71 		// assert cl.cLevels() == cLevels()
72 		for (int i = 0; i < _values.length; i++)
73 		{
74 			if (_values[i] < cl._values[i])
75 				return true;
76 			else if (_values[i] > cl._values[i])
77 				return false;
78 		}
79 		return true; // they are equal
80 	}
81 
82 	bool equal(ClSymbolicWeight cl) const pure @safe
83 	{
84 		for (int i = 0; i < _values.length; i++)
85 		{
86 			if (_values[i] != cl._values[i])
87 				return false;
88 		}
89 		return true; // they are equal
90 	}
91 
92 	bool greaterThan(ClSymbolicWeight cl) const pure
93 	{
94 		return !this.lessThanOrEqual(cl);
95 	}
96 
97 	bool greaterThanOrEqual(ClSymbolicWeight cl) const pure
98 	{
99 		return !this.lessThan(cl);
100 	}
101 
102 	bool isNegative() const pure
103 	{
104 		return this.lessThan(clsZero);
105 	}
106 
107 	double asDouble() const pure @safe
108 	{
109 		double sum = 0;
110 		double factor = 1;
111 		double multiplier = 1000;
112 		foreach_reverse(i; _values)
113 		{
114 			sum += i * factor;
115 			factor *= multiplier;
116 		}
117 		return sum;
118 	}
119 
120 	override string toString() const
121 	{
122 		return _values.to!string();
123 	}
124 
125 	ulong cLevels() const pure @safe nothrow
126 	{
127 		return _values.length;
128 	}
129 
130 	private immutable double[] _values;
131 }