Skip to content

Commit cac16b8

Browse files
committed
Converted MOST of the Expression subclasses into case classes, which means you can remove new operator for them all.
be careful not when using EqualExpression to compare two character types, since you need to pass in the third argument which is the non-integer type.
1 parent 64e41d4 commit cac16b8

66 files changed

Lines changed: 576 additions & 619 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

dynamicProgramming/src/main/scala/org/combinators/README.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
1-
# DP Generators that Compile:
1+
The `EnhancedModel` adds additional capabilities to support generating various DP problems.
2+
3+
```
4+
class EnhancedModel(val problem:String,
5+
val input:Seq[ArgExpression],
6+
val subproblemType:ArgumentType, // Type of solution
7+
val solutionType:ArgumentType, // Type of return value
8+
val solution:SubproblemInvocation,
9+
val definition:Definition,
10+
val answer:Definition, // all existing Expression should just use ExpressionDefinition(expr)
11+
val mode:ProblemOrder = Canonical())
12+
```
213

3-
- bottomUp/twoSequences/longestCommonSubsequence (missing cases)
4-
- bottomUp/twoSequences/uncrossedLines (missing cases)
5-
- bottomUp/oneSequence/tribonacci
6-
- topDown/oneSequence/tribonacci
7-
-
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
This `cogen` package contains the earliest attempts to use CoGen to generate dynamic programming (DP) solutions in Java.
2+
3+
Starting from available Java implementations of numerous DP problems, in the initial stage of this project the goal was to be able
4+
to replicate these code using straight CoGen code. Along the way, one hoped it would be possible to find opportunities to reuse
5+
CoGen methods to be able to normalize the entire process.
6+
7+
# Bottom Up
8+
9+
* Pascal's Triangle
10+
* One Sequence
11+
- DecodeWays
12+
- Fibonacci
13+
- MaxSubArray
14+
- Tribonacci
15+
* Two Sequences
16+
- LongestCommonSubSequence
17+
- UncrossedLines
18+
19+
# Top Down
20+
21+
* Pascal's Triangle
22+
* One Sequence
23+
- Delete And Earn
24+
- House Robber
25+
- JumpTo
26+
- Tribonacci
27+
28+
# Summary
29+
30+
While various DP problems can be generated through straight CoGen code, this approach is untenable and ultimately did not really result
31+
in reusable methods for these problems.
32+

dynamicProgramming/src/main/scala/org/combinators/archive/cogen/bottomUp/oneSequence/decodeways/DecodeWaysMain.scala

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -134,29 +134,26 @@ object DPDirectToDiskMain extends IOApp {
134134

135135
val zero: LiteralInt = new LiteralInt(0)
136136
val one: LiteralInt = new LiteralInt(1)
137-
val ascii_zero:LiteralChar = new LiteralChar('0')
137+
val ascii_zero:LiteralChar = LiteralChar('0')
138138
val two: LiteralInt = new LiteralInt(2)
139139

140140
// what was passed into constructor of the original class
141141
val input:InputExpression = new InputExpression("s") // might also need to pass in "type"
142142

143-
val bound = List(new ArgExpression(0, "text1", new StringType(), "r"), new ArgExpression(1, "text2", new StringType(), "c"))
143+
val bound = List(ArgExpression(0, "text1", StringType(), "r"), ArgExpression(1, "text2", StringType(), "c"))
144144

145-
val r: IteratorExpression = new IteratorExpression(0, "r") // only one argument, n
146-
val c: IteratorExpression = new IteratorExpression(1, "c") // only one argument, n
147-
148-
val im1 = new SubtractionExpression(r, one)
149-
val im2 = new SubtractionExpression(c, two)
145+
val r: IteratorExpression = IteratorExpression(0, "r") // only one argument, n
146+
val c: IteratorExpression = IteratorExpression(1, "c") // only one argument, n
150147

151148
val DecodeWays = new Model("DecodeWays",
152149
bound,
153150
cases = List(
154151
// s.length() == n
155-
( Some(new EqualExpression(new StringLengthExpression(input), one)), one ),
152+
( Some(StringLengthExpression(input) == one), one ),
156153
// s.CharAt(n) == '0')
157-
( Some(new EqualExpression(new CharAtExpression(input, one), ascii_zero)), zero),
154+
( Some(CharAtExpression(input, one) == ascii_zero), zero),
158155
// HACK == helper(n-1)
159-
( None, new SubproblemExpression(Seq(im1)))
156+
( None, SubproblemExpression(Seq(r - one)))
160157
)
161158
)
162159

dynamicProgramming/src/main/scala/org/combinators/archive/cogen/bottomUp/twoSequences/longestCommonSubsequence/LCSProvider.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ trait LCSProvider extends DPObjectOrientedProvider {
3939

4040
// NOTE: these tests are in the wrong place, since we defer test gen to later
4141
val tests = Seq(
42-
new TestExample("fib0", new LiteralStringPair("ACTG", "CGATC"), new LiteralInt(2), new LiteralString("AC")) // for now, leave solution as None
42+
new TestExample("fib0", LiteralStringPair("ACTG", "CGATC"), new LiteralInt(2), LiteralString("AC")) // for now, leave solution as None
4343
)
4444

4545
for {

dynamicProgramming/src/main/scala/org/combinators/archive/cogen/bottomUp/twoSequences/longestCommonSubsequence/LongestCommonSubsequenceObjectOrientedProvider.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,9 +175,9 @@ trait LongestCommonSubsequenceObjectOrientedProvider extends TwoSequencesUtility
175175

176176
// https://en.wikipedia.org/wiki/Maximum_subarray_problem
177177
val wiki_test = new TestExample("wiki",
178-
new LiteralStringPair("GAC", "AGCAT"),
178+
LiteralStringPair("GAC", "AGCAT"),
179179
new LiteralInt(2),
180-
new LiteralString("GA")
180+
LiteralString("GA")
181181
)
182182

183183
for {
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
We designed a Model class that was meant to provide all information for a DP problem.
2+
3+
```class Model(val problem:String,
4+
val bounds: List[ArgExpression],
5+
val cases: List[(Option[Expression], Expression)],
6+
val retrieveLabel: String = "take sub-solution")
7+
```
8+
9+
It is best to explain this with a simple model that captures the Fibonacci domain
10+
11+
# Fibonacci
12+
13+
```
14+
val zero: LiteralInt = new LiteralInt(0)
15+
val one: LiteralInt = new LiteralInt(1)
16+
val two: LiteralInt = new LiteralInt(2)
17+
18+
val bound = List(ArgExpression(0, "n", IntegerType(), "i"))
19+
20+
val i: IteratorExpression = IteratorExpression(0, "i")
21+
22+
new Model("Fibonacci",
23+
bound,
24+
cases = List(
25+
(Some(i == zero), zero),
26+
(Some(i == one), one),
27+
(None, SubproblemExpression(Seq(i - one)) + SubproblemExpression(Seq(i - two)) )
28+
)
29+
)
30+
}
31+
```
32+
33+
The `bounds` represents the arguments to the problem -- in this case, Fibonacci(n). `n` is an argument of type integer, and it is the 0th argument
34+
for this problem. The variable "i" is to be used with iterating over subproblems in `n`.
35+
36+
The `cases` represents an ordered list of pairs, where each pair has an optional guard that, if true, yields the corresponding expression.
37+
38+
Thus `Fibonacci(0) = 0` and `Fibonacci(1) = 1`. The interesting case is the recursive case, namely that `Fibonacci(i)` is computed by adding together
39+
the resulting subexpression `Fibonacci(i-1)` and `Fibonacci(i-2)`.
40+
41+
# Solutions with Model
42+
43+
* DecodeWays
44+
* Fibonacci
45+
* JumpTo
46+
* UniquePaths
47+
* CoinChange
48+
* KnapSack
49+
* MaxSubArray
50+
* ThreeStrings LongestCommonSubsequence
51+
* DistinctSubsequences
52+
* LongestCommonSubsequence
53+
* MinimumEditDistance
54+
* NeedlemanWunschSequenceAlignment
55+
* UncrossedLines
56+
57+
In theory, each of these should support both a bottom-up generation and a top-down generation, using the `BottomUpStrategy` and `TopDownStrategy` found
58+
in the `dp.original.BottomUpStrategy` and `dp.original.TopDownStrategy` traits.

dynamicProgramming/src/main/scala/org/combinators/archive/unenhancedModels/boilerplate/NWSA/NWSAProvider.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ trait NWSAProvider extends DPObjectOrientedProvider {
3939

4040
// NOTE: these tests are in the wrong place, since we defer test gen to later
4141
val tests = Seq(
42-
new TestExample("fib0", new LiteralStringPair("ACTG", "CGATC"), new LiteralInt(2), new LiteralString("AC")) // for now, leave solution as None
42+
new TestExample("fib0", LiteralStringPair("ACTG", "CGATC"), new LiteralInt(2), LiteralString("AC")) // for now, leave solution as None
4343
)
4444

4545
for {

dynamicProgramming/src/main/scala/org/combinators/archive/unenhancedModels/boilerplate/coinChange/CoinChangeProvider.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ trait CoinChangeProvider extends DPObjectOrientedProvider {
4545

4646
// NOTE: these tests are in the wrong place, since we defer test gen to later
4747
val tests = Seq(
48-
new TestExample("test1", new LiteralArray(Array(1,2,5)), new LiteralInt(3), new LiteralString("test")) // HACK: amount (11) is not here!
48+
new TestExample("test1", new LiteralArray(Array(1,2,5)), new LiteralInt(3), LiteralString("test")) // HACK: amount (11) is not here!
4949
)
5050

5151
for {

dynamicProgramming/src/main/scala/org/combinators/archive/unenhancedModels/boilerplate/fibonacci/FibonacciMainJava.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,20 +99,20 @@ object FibonacciMainDirectToDiskMain extends IOApp {
9999
val two: LiteralInt = new LiteralInt(2)
100100

101101
// Fibonacci has a single integer argument
102-
val bound = List(new ArgExpression(0, "n", new IntegerType(), "i"))
102+
val bound = List(ArgExpression(0, "n", IntegerType(), "i"))
103103

104104
// COULD be inferred from the ArgExpression list, but this lets us name variable to use in iterator
105-
val n: IteratorExpression = new IteratorExpression(0, "i") // only one argument, i
105+
val n: IteratorExpression = IteratorExpression(0, "i") // only one argument, i
106106

107-
val im1 = new SubtractionExpression(n, one)
108-
val im2 = new SubtractionExpression(n, two)
107+
val im1 = SubtractionExpression(n, one)
108+
val im2 = SubtractionExpression(n, two)
109109

110110
val Fib = new Model("Fibonacci",
111111
bound,
112112
cases = List(
113-
( Some(new EqualExpression(n, zero)), zero ),
114-
( Some(new EqualExpression(n, one)), one ),
115-
( None, new AdditionExpression(new SubproblemExpression(Seq(im1)), new SubproblemExpression(Seq(im2))) )
113+
( Some(n == zero), zero ),
114+
( Some(n == one), one ),
115+
( None, SubproblemExpression(Seq(im1)) + SubproblemExpression(Seq(im2)) )
116116
)
117117
)
118118

dynamicProgramming/src/main/scala/org/combinators/archive/unenhancedModels/boilerplate/jumpTo/JumpToMain.scala

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -131,27 +131,25 @@ object JumpToMainDirectToDiskMain extends IOApp {
131131

132132
val zero: LiteralInt = new LiteralInt(0)
133133
val one: LiteralInt = new LiteralInt(1)
134-
val ascii_zero:LiteralChar = new LiteralChar('0')
134+
val ascii_zero:LiteralChar = LiteralChar('0')
135135
val two: LiteralInt = new LiteralInt(2)
136136

137137
// what was passed into constructor of the original class
138138
val input:InputExpression = new InputExpression("array") // might also need to pass in "type"
139139

140-
val bound = List(new ArgExpression(0, "array", new IntegerArrayType(), "i"))
140+
val bound = List(ArgExpression(0, "array", IntegerArrayType(), "i"))
141141

142-
val n: IteratorExpression = new IteratorExpression(0, "i") // only one argument, n
142+
val n: IteratorExpression = IteratorExpression(0, "i") // only one argument, n
143143

144-
val im1 = new SubtractionExpression(n, one)
145-
146144
val JumpTo = new Model("JumpTo",
147145
bound,
148146
cases = List(
149147
// array.length()-1 < n
150-
( Some(new LessThanExpression(new SubtractionExpression(new ArrayLengthExpression(input), one), n)), zero),
148+
( Some(ArrayLengthExpression(input) - one < n), zero),
151149
// array.length()-1 = n
152-
( Some(new EqualExpression(new SubtractionExpression(new ArrayLengthExpression(input), one), n)), zero),
150+
( Some(ArrayLengthExpression(input) - one == n), zero),
153151
// HACK == helper(n-1)
154-
( None, new SubproblemExpression(Seq(im1)))
152+
( None, SubproblemExpression(Seq(n - one)))
155153
)
156154
)
157155

0 commit comments

Comments
 (0)