Skip to content

Commit 8329eda

Browse files
committed
In the middle of creating Array support for inBetween/Scala
1 parent a54a9ac commit 8329eda

12 files changed

Lines changed: 281 additions & 40 deletions

File tree

builder/src/main/scala/org/combinators/ep/builder/scala/paradigm/ffi/TreesAST.scala

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ trait TreesAST extends InbetweenTreesAST { self: ParametricPolymorphismAST & Bas
1717
type Node <: treesOpsOverride.Node
1818
}
1919

20-
21-
2220
trait Tree extends treesOps.Tree with scalaBase.ooOverrides.ClassReferenceType {
2321
def qualifiedClassName: Seq[any.Name] = qualifiedClassNameTree
2422
}
@@ -45,7 +43,6 @@ trait TreesAST extends InbetweenTreesAST { self: ParametricPolymorphismAST & Bas
4543
}
4644
}
4745

48-
4946
val qualifiedClassNameTree: Seq[any.Name] = Seq("org", "combinators", "ep", "util", "Tree").map(n => scalaBaseFactory.name(n, n))
5047
val qualifiedClassNameLeaf: Seq[any.Name] = Seq("org", "combinators", "ep", "util", "Leaf").map(n => scalaBaseFactory.name(n, n))
5148
val qualifiedClassNameNode: Seq[any.Name] = Seq("org", "combinators", "ep", "util", "Node").map(n => scalaBaseFactory.name(n, n))

dynamicProgramming/src/main/scala/org/combinators/dp/Utility.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ trait Utility {
5252
case IntegerType() => TypeRep.Int
5353
case StringType() => TypeRep.String
5454
case CharType() => TypeRep.Char
55+
case BooleanType() => TypeRep.Boolean
5556

5657
case _ => ???
5758
}

dynamicProgramming/src/main/scala/org/combinators/dp/enhanced/BottomUpStrategy.scala

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,6 @@ trait BottomUpStrategy extends Utility with EnhancedUtility {
142142
theType <- return_type_based_on_model(model)
143143
_ <- setReturnType(theType)
144144

145-
// ONLY ONE HERE
146-
arrayType <- toTargetLanguageType(arTypes(model))
147-
148145
// cannot seem to do this in Constructor because it insists on using "int" for TypeRep.Int within ConstructorContext which
149146
// seems to be different from Integer which occurs in MethodBodyContext
150147
dp <- ooParadigm.methodBodyCapabilities.getMember(self, dpName)
@@ -395,16 +392,25 @@ trait BottomUpStrategy extends Utility with EnhancedUtility {
395392
/**
396393
* Constructor now takes the responsibility of taking the arguments to the problem. Takes
397394
* in a sequence of arguments, and auto-initializes all possible fields.
395+
*
396+
* args are "name", then "name_init", then TYPE.
397+
*
398+
* name_init would be the parameter to constructor;
399+
* name is field in the class
400+
* TYPE is type for both
398401
*/
399-
def create_bottom_up_constructor(args: Seq[(Name, Type)]): Generator[ConstructorContext, Unit] = {
402+
def create_bottom_up_constructor(args: Seq[(Name, Name, Type)]): Generator[ConstructorContext, Unit] = {
400403
import ooParadigm.constructorCapabilities._
401404

405+
val formalArgs = args.map(arg => (arg._2, arg._3))
406+
val fieldArgs = args.map(arg => (arg._1, arg._3))
407+
402408
for {
403-
_ <- setParameters(args)
409+
_ <- setParameters(formalArgs)
404410
real_args <- getArguments()
405411

406-
_ <- forEach(real_args) { arg => for {
407-
_ <- initializeField(arg._1, arg._3)
412+
_ <- forEach(real_args.zip(fieldArgs)) { pair => for {
413+
_ <- initializeField(pair._2._1, pair._1._3)
408414
} yield ()
409415
}
410416

@@ -424,6 +430,7 @@ trait BottomUpStrategy extends Utility with EnhancedUtility {
424430
case _ => model.solution.order
425431
}
426432

433+
println("Make Bottom Up Fix Array Type!")
427434
for {
428435
arrayType <- toTargetLanguageType(arTypes(model))
429436

@@ -433,12 +440,17 @@ trait BottomUpStrategy extends Utility with EnhancedUtility {
433440
} yield ()
434441
}
435442

443+
436444
_ <- addField(dpName, arrayType) // this becomes "int" if I use arrayType
445+
intType <- toTargetLanguageType(TypeRep.Int)
446+
stringType <- toTargetLanguageType(TypeRep.String)
447+
_ <- addField(names.mangle("HACK"), intType)
448+
_ <- addField(names.mangle("HACK2"), stringType)
437449

438450
constArgs <- forEach(model.input) { bexpr =>
439451
for {
440452
tpe <- map_type_in_class(bexpr.argType)
441-
} yield (names.mangle(bexpr.name), tpe)
453+
} yield (names.mangle(bexpr.name), names.mangle(bexpr.name + "_"), tpe) // in some OO languages, i.e., scala, param name must be different
442454
}
443455
_ <- addConstructor(create_bottom_up_constructor(constArgs))
444456

dynamicProgramming/src/main/scala/org/combinators/dp/enhanced/EnhancedDPObjectOrientedProvider.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import org.combinators.cogen.paradigm.control.Imperative
77
import org.combinators.cogen.paradigm.ffi.{Arithmetic, Arrays, Assertions, Booleans, Console, Equality, RealArithmetic, Strings}
88
import org.combinators.cogen.paradigm.{AnyParadigm, Generics, ObjectOriented, ParametricPolymorphism}
99
import org.combinators.dp.{BottomUp, GenerationOption, TestExample, TopDown}
10-
import org.combinators.models.{EnhancedModel, LiteralArray, LiteralArrayPair, LiteralBoolean, LiteralExpression, LiteralInt, LiteralPair, LiteralString, LiteralStringPair, LiteralStringTriple, LiteralTriple}
10+
import org.combinators.models.{EnhancedModel, LiteralArray, LiteralArrayPair, LiteralBoolean, LiteralChar, LiteralExpression, LiteralInt, LiteralPair, LiteralString, LiteralStringPair, LiteralStringTriple, LiteralTriple}
1111

1212
/** Any OO approach will need to properly register type mappings and provide a default mechanism for finding a class
1313
* in a variety of contexts. This trait provides that capability
@@ -43,6 +43,7 @@ trait EnhancedDPObjectOrientedProvider extends EnhancedDPProvider with EnhancedU
4343
case lit: LiteralInt => paradigm.methodBodyCapabilities.reify(TypeRep.Int, lit.literal)
4444
case bool: LiteralBoolean => paradigm.methodBodyCapabilities.reify(TypeRep.Boolean, bool.literal)
4545
case str: LiteralString => paradigm.methodBodyCapabilities.reify(TypeRep.String, str.literal)
46+
case chr: LiteralChar => paradigm.methodBodyCapabilities.reify(TypeRep.Char, chr.literal)
4647

4748
case _ => ??? // error in all other circumstances
4849
}
@@ -56,6 +57,7 @@ trait EnhancedDPObjectOrientedProvider extends EnhancedDPProvider with EnhancedU
5657

5758
val the_test_type = test.answer match {
5859
case _:LiteralInt => toTargetLanguageType(TypeRep.Int)
60+
case _:LiteralChar => toTargetLanguageType(TypeRep.Char)
5961
case _:LiteralBoolean => toTargetLanguageType(TypeRep.Boolean)
6062
case _:LiteralString => toTargetLanguageType(TypeRep.String)
6163
case _:LiteralTriple => toTargetLanguageType(TypeRep.Int) // triple means three separate integer values

dynamicProgramming/src/main/scala/org/combinators/dp/enhanced/EnhancedUtility.scala

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package org.combinators.dp.enhanced
22

3-
import org.combinators.models.{BooleanType, EnhancedModel, IntegerType, StringType}
3+
import org.combinators.models.{BooleanType, CharType, EnhancedModel, IntegerType, StringType}
44
import org.combinators.cogen.TypeRep
55
import org.combinators.cogen.Command.Generator
66
import org.combinators.cogen.NameProvider
@@ -33,6 +33,10 @@ trait EnhancedUtility {
3333
intType <- toTargetLanguageType(TypeRep.Int)
3434
} yield intType
3535

36+
case _:CharType => for {
37+
charType <- toTargetLanguageType(TypeRep.Char)
38+
} yield charType
39+
3640
case _:BooleanType => for {
3741
boolType <- toTargetLanguageType(TypeRep.Boolean)
3842
} yield boolType
@@ -53,6 +57,10 @@ trait EnhancedUtility {
5357
intType <- toTargetLanguageType(TypeRep.Int)
5458
} yield intType
5559

60+
case _:CharType => for {
61+
charType <- toTargetLanguageType(TypeRep.Char)
62+
} yield charType
63+
5664
case _:BooleanType => for {
5765
boolType <- toTargetLanguageType(TypeRep.Boolean)
5866
} yield boolType
@@ -73,6 +81,10 @@ trait EnhancedUtility {
7381
intType <- toTargetLanguageType(TypeRep.Int)
7482
} yield intType
7583

84+
case _:CharType => for {
85+
charType <- toTargetLanguageType(TypeRep.Char)
86+
} yield charType
87+
7688
case _:BooleanType => for {
7789
boolType <- toTargetLanguageType(TypeRep.Boolean)
7890
} yield boolType
@@ -93,6 +105,10 @@ trait EnhancedUtility {
93105
intType <- toTargetLanguageType(TypeRep.Int)
94106
} yield intType
95107

108+
case _:CharType => for {
109+
charType <- toTargetLanguageType(TypeRep.Char)
110+
} yield charType
111+
96112
case _:BooleanType => for {
97113
boolType <- toTargetLanguageType(TypeRep.Boolean)
98114
} yield boolType

dynamicProgramming/src/main/scala/org/combinators/dp/enhanced/TopDownStrategy.scala

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -142,17 +142,26 @@ trait TopDownStrategy extends Utility with EnhancedUtility {
142142
/**
143143
* Constructor now takes the responsibility of taking the arguments to the problem. Takes
144144
* in a sequence of arguments, and auto-initializes all possible fields.
145+
*
146+
* args are "name", then "name_init", then TYPE.
147+
*
148+
* name_init would be the parameter to constructor;
149+
* name is field in the class
150+
* TYPE is type for both
145151
*/
146-
def createConstructor(model:EnhancedModel, useMemo:Boolean, args: Seq[(Name, Type)]): Generator[ConstructorContext, Unit] = {
152+
def createConstructor(model:EnhancedModel, useMemo:Boolean, args: Seq[(Name, Name, Type)]): Generator[ConstructorContext, Unit] = {
147153
import ooParadigm.constructorCapabilities._
148154

155+
val formalArgs = args.map(arg => (arg._2, arg._3))
156+
val fieldArgs = args.map(arg => (arg._1, arg._3))
157+
149158
for {
150-
_ <- setParameters(args)
151-
real_args <- getArguments()
159+
_ <- setParameters(formalArgs)
160+
real_args <- getArguments() // these now contain the "_init" expressions
152161

153-
_ <- forEach(real_args) { arg => for {
154-
_ <- initializeField(arg._1, arg._3)
155-
} yield ()
162+
_ <- forEach(real_args.zip(fieldArgs)) { pair => for {
163+
_ <- initializeField(pair._2._1, pair._1._3)
164+
} yield ()
156165
}
157166

158167
_ <- if (useMemo) {
@@ -217,7 +226,7 @@ trait TopDownStrategy extends Utility with EnhancedUtility {
217226
constArgs <- forEach(model.input) { bexpr =>
218227
for {
219228
tpe <- map_type_in_class(bexpr.argType)
220-
} yield (names.mangle(bexpr.name), tpe)
229+
} yield (names.mangle(bexpr.name), names.mangle(bexpr.name + "_"), tpe) // in some OO languages, i.e., scala, param name must be different
221230
}
222231

223232
_ <- addConstructor(createConstructor(model, useMemo, constArgs)) // FIX HACK
Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
package org.combinators.models
2+
3+
/**
4+
* sbt "dp/runMain org.combinators.modelTests.Glossary [bottomUp | topDown | topDownMemo]
5+
*
6+
* Creates output files in target/bottomUp or target\topDown or target\topDownMemo
7+
*/
8+
9+
import cats.effect.{ExitCode, IO, IOApp}
10+
import org.apache.commons.io.FileUtils
11+
import org.combinators.archive.cogen.bottomUp.twoSequences.longestCommonSubsequence.LCSMainJava
12+
import org.combinators.archive.unenhancedModels.boilerplate.unenhancedUncrossedLines.UnenhancedUncrossedLinesMainJava
13+
import org.combinators.archive.unenhancedModels.models.twoSequences.{LongestCommonSubsequenceModel, UncrossedLinesModel}
14+
import org.combinators.dp.enhanced.EnhancedMainInterface
15+
import org.combinators.dp.{BottomUp, GenerationOption, TopDown}
16+
import org.combinators.cogen.{FileWithPath, FileWithPathPersistable}
17+
import FileWithPathPersistable._
18+
import org.combinators.models.boilerplate.grid._
19+
import org.combinators.models.boilerplate.integer._
20+
import org.combinators.models.boilerplate.oneSequence._
21+
import org.combinators.models.boilerplate.strings._
22+
import org.combinators.models.boilerplate.twoSequences._
23+
24+
import java.nio.file.{Path, Paths}
25+
import scala.collection.Seq
26+
27+
class GlossaryScala {
28+
29+
val persistable = FileWithPathPersistable[FileWithPath]
30+
31+
def directToDiskTransaction(targetDirectory: Path, files: Seq[FileWithPath]): IO[Unit] = {
32+
IO {
33+
print("Computing Files...")
34+
println("[OK]")
35+
if (targetDirectory.toFile.exists()) {
36+
print(s"Cleaning Target Directory ($targetDirectory)...")
37+
FileUtils.deleteDirectory(targetDirectory.toFile)
38+
println("[OK]")
39+
}
40+
print("Persisting Files...")
41+
files.foreach(file => persistable.persistOverwriting(targetDirectory, file))
42+
println("[OK]")
43+
}
44+
}
45+
46+
def runDirectToDisc(targetDirectory: Path,files: Seq[FileWithPath]): IO[ExitCode] = {
47+
for {
48+
_ <- directToDiskTransaction(targetDirectory, files)
49+
} yield ExitCode.Success
50+
}
51+
}
52+
53+
object GlossaryScalaToDiskMain extends IOApp {
54+
55+
// choose one of these to pass in
56+
val topDown = TopDown()
57+
val topDownWithMemo = TopDown(memo = true)
58+
val bottomUp = BottomUp()
59+
60+
// declare the working versions for each problem in the enhanced list
61+
val known_enhanced_solutions:Seq[(EnhancedMainInterface, EnhancedModel, Seq[GenerationOption])] = Seq(
62+
(new BellNumberMainJava(), BellNumberDirectToDiskMain.model, Seq(topDown, topDownWithMemo, bottomUp)),
63+
(new CountSquaresMainJava(), CountSquaresToDiskMain.model, Seq(topDown, topDownWithMemo, bottomUp)),
64+
(new DiceThrowMainJava(), DiceThrowDirectToDiskMain.model, Seq(topDown, topDownWithMemo, bottomUp)),
65+
(new FibonacciEnhancedMainJava(), FibonacciEnhancedMainToDiskMain.model, Seq(topDown, topDownWithMemo, bottomUp)),
66+
(new InterleaveStringsMainJava(), InterleaveStringsToDiskMain.model, Seq(topDown, topDownWithMemo, bottomUp)),
67+
(new LongestCommonSubsequenceMainJava, LongestCommonSubsequenceToDiskMain.model, Seq(topDown, topDownWithMemo, bottomUp)),
68+
(new MinCostClimbingStairMain(), MinCostClimbingStairToDiskMain.model, Seq(topDown, topDownWithMemo, bottomUp)),
69+
(new PerfectSquareMainJava(), PerfectSquareMainDirectToDiskMain.model, Seq(topDown, topDownWithMemo, bottomUp)),
70+
(new ThreeStringsLCSMainJava(), ThreeStringsLCSToDiskMain.model, Seq(topDown, topDownWithMemo, bottomUp)),
71+
(new UncrossedLinesMainJava(), UncrossedLinesDirectDiskToMain.model, Seq(topDown, topDownWithMemo, bottomUp)),
72+
// (new NeedlemanWunschSequenceAlignmentMainJava(), NeedlemanWunschSequenceAlignmentToDiskMain.model, Seq(topDown, topDownWithMemo, bottomUp)),
73+
// (new DistinctSubsequencesMainJava(), DistinctSubsequencesToDiskMain.model, Seq(topDown, topDownWithMemo, bottomUp)),
74+
// (new WildcardPatternMatchingMainJava(), WildcardPatternMatchingToDiskMain.model, Seq(topDown, topDownWithMemo, bottomUp)),
75+
// (new ShortestCommonSupersequenceMainJava(), ShortestCommonSupersequenceToDiskMain.model, Seq(topDown, topDownWithMemo, bottomUp)),
76+
(new TribonacciMainJava(), TribonacciToDiskMain.model, Seq(topDown, topDownWithMemo, bottomUp)),
77+
(new UniquePathsMainJava(), UniquePathsToDiskMain.model, Seq(topDown, topDownWithMemo, bottomUp)),
78+
(new MinPathSumMainJava(), MinPathSumToDiskMain.model, Seq(topDown, topDownWithMemo, bottomUp)),
79+
80+
// generates but has flawed logic because of the transformation of (r,c) into (i,j)
81+
// CHALLENGING (new MatrixChainMultiplicationMainJava(), MatrixChainMultiplicationMainDirectToDiskMain.model, Seq(topDown, topDownWithMemo, bottomUp)),
82+
)
83+
84+
// below are the individual DP problems generated and added to `all_files`.
85+
def top_down_memo_files(): Seq[FileWithPath] = {
86+
87+
// UncrossedLinesMainJava and LCSMainJava still don't work
88+
89+
val mcm_td = (new MatrixChainMultiplicationMainTopDownJava(), MatrixChainMultiplicationMainTopDownDirectToDiskMain.model, Seq(topDown, topDownWithMemo))
90+
val just_td = Seq(mcm_td)
91+
92+
val others = (just_td ++ known_enhanced_solutions).filter(triple
93+
=> triple._3.contains(TopDown(memo = true))).
94+
flatMap(triple => triple._1.filesToGenerate(triple._2, TopDown(memo = true)))
95+
96+
others
97+
}
98+
99+
// below are the individual DP problems generated and added to `all_files`.
100+
def top_down(): Seq[FileWithPath] = {
101+
// val ul = new UncrossedLinesMainJava().filesToGenerate(new UncrossedLinesModel().instantiate(), TopDown())
102+
//val lcs = new LCSMainJava().filesToGenerate(new LongestCommonSubsequenceModel().instantiate(), TopDown()) [HEINEMAN: not working]
103+
// val kp = new KnapsackMainJava().filesToGenerate(new KnapsackModel().instantiate(), TopDown()) [HEINEMAN: not working]
104+
//val nwsa = new NWSAMainJava().filesToGenerate(new NeedlemanWunschSequenceAlignmentModel().instantiate(), TopDown()) [HEINEMAN: not working]
105+
106+
val mcm_td = (new MatrixChainMultiplicationMainTopDownJava(), MatrixChainMultiplicationMainTopDownDirectToDiskMain.model, Seq(topDown, topDownWithMemo))
107+
val just_td = Seq(mcm_td)
108+
109+
val others = (just_td ++ known_enhanced_solutions).filter(triple
110+
=> triple._3.contains(TopDown())).
111+
flatMap(triple => triple._1.filesToGenerate(triple._2, TopDown()))
112+
113+
others
114+
}
115+
116+
def bottom_up_files() : Seq[FileWithPath] = {
117+
val ul = new UnenhancedUncrossedLinesMainJava().filesToGenerate(new UncrossedLinesModel().instantiate(), BottomUp())
118+
val lcs = new LCSMainJava().filesToGenerate(new LongestCommonSubsequenceModel().instantiate(), BottomUp())
119+
120+
val mcm_bot = (new MatrixChainMultiplicationMainBottomUpJava(), MatrixChainMultiplicationMainBottomUpDirectToDiskMain.model, Seq(bottomUp))
121+
val just_bot = Seq(mcm_bot)
122+
123+
val others = (just_bot ++ known_enhanced_solutions).filter(triple
124+
=> triple._3.contains(BottomUp())).
125+
flatMap(triple => triple._1.filesToGenerate(triple._2, BottomUp()))
126+
127+
others
128+
}
129+
130+
def run(args: List[String]): IO[ExitCode] = {
131+
val choice = if (args.isEmpty) {
132+
bottomUp // <------ CHANGE this manually when you run, to generate topDown or topDownWithMemo -- BOTTOMUP NOT YET WORKING
133+
} else {
134+
args(0).toLowerCase match {
135+
case "topdown" => topDown
136+
case "bottomup" => bottomUp
137+
case "topdownmemo" => topDownWithMemo
138+
case "topdownwithmemo" => topDownWithMemo
139+
case _ =>
140+
print (s"Unknown option: ${args(0)}. Must be either 'topDown', 'bottomUp' or 'topDownMemo'.")
141+
???
142+
}
143+
}
144+
145+
val targetDirectory:Path = Paths.get("target", choice.name)
146+
147+
for {
148+
_ <- IO {
149+
println("Initializing Generator...")
150+
println(s"Output will appear in: ${targetDirectory}")
151+
}
152+
main <- IO { new Glossary() }
153+
154+
result <- if (choice == topDown) {
155+
main.runDirectToDisc(targetDirectory, top_down())
156+
} else if (choice == topDownWithMemo) {
157+
main.runDirectToDisc(targetDirectory, top_down_memo_files())
158+
} else {
159+
main.runDirectToDisc(targetDirectory, bottom_up_files())
160+
}
161+
162+
_ <- IO { println("Make sure you run the scripts to 'fix' the generated code.") }
163+
} yield result
164+
}
165+
}

0 commit comments

Comments
 (0)