changeset 43:96b2fcb746bf

Add support for generating programs with only a certain set of operators to allow work with slightly larger problem sizes
author Mike Pavone <pavone@retrodev.com>
date Sun, 11 Aug 2013 02:16:14 -0700
parents 1cadb591eef1
children e795f7179456
files src/bv.tp
diffstat 1 files changed, 137 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/bv.tp	Sun Aug 11 00:37:34 2013 -0700
+++ b/src/bv.tp	Sun Aug 11 02:16:14 2013 -0700
@@ -394,6 +394,130 @@
 					allOfSize: (n - 1) inFold?: 0
 				}
 
+				allOfSize:inFold?:withOps <- :n :infold? :ops {
+					if: n = 1 {
+						res <- #[one zero input]
+						if: infold? = 2 {
+							res append: acc
+							res append: val
+						}
+						res
+					} else: {
+						res <- #[]
+						origops <- ops
+						if: (ops and _opTfold) > 0 {
+							ops <- ops and _maskRemoveFold
+						}
+						if: (ops and (_opNot or _opShl1 or _opShr1 or _opShr4 or _opShr16)) > 0 {
+							foreach: (allOfSize: n - 1 inFold?: infold? withOps: ops) :idx exp {
+								if: (ops and _opNot) > 0 {
+									res append: (opNot: exp)
+								}
+								if: (ops and _opShl1) > 0 {
+									res append: (shl1: exp)
+								}
+								if: (ops and _opShr1) > 0 {
+									res append: (shr1: exp)
+								}
+								if: (ops and _opShr4) > 0 {
+									res append: (shr4: exp)
+								}
+								if: (ops and _opShr16) > 0 {
+									res append: (shr16: exp)
+								}
+							}
+						}
+						if: n > 2 {
+							numLeft <- 1
+							argTotal <- n - 1
+							if: (ops and (_opAnd or _opOr or _opXor or _opPlus)) > 0 {
+								while: { numLeft < argTotal } do: {
+									numRight <- argTotal - numLeft
+									choicesRight <- (allOfSize: numRight inFold?: infold? withOps: ops)
+									foreach: (allOfSize: numLeft inFold?: infold? withOps: ops) :idx leftExp {
+										foreach: choicesRight :idx rightExp {
+											if: (ops and _opAnd) > 0 {
+												res append: (opAnd: leftExp rightExp)
+											}
+											if: (ops and _opOr) > 0 {
+												res append: (opOr: leftExp rightExp)
+											}
+											if: (ops and _opXor) > 0 {
+												res append: (opXor: leftExp rightExp)
+											}
+											if: (ops and _opPlus) > 0 {
+												res append: (plus: leftExp rightExp)
+											}
+										}
+									}
+									numLeft <- numLeft + 1
+								}
+							}
+							if: n > 3 {
+								numLeft <- 1
+								limitLeft <- n - 2
+								if: (ops and _opIf0) > 0 {
+									while: { numLeft < limitLeft } do: {
+										numMid <- 1
+										limitMid <- n - (1 + numLeft)
+										while: { numMid < limitMid } do: {
+											numRight <- n - (1 + numLeft + numMid)
+											choicesRight <- (allOfSize: numRight inFold?: infold? withOps: ops)
+											choicesMid <- (allOfSize: numMid inFold?: infold? withOps: ops)
+											foreach: (allOfSize: numLeft inFold?: infold? withOps: ops ) :idx leftExp {
+												foreach: choicesMid :idx midExp {
+													foreach: choicesRight :idx rightExp {
+														res append: (if0: leftExp then: midExp else: rightExp)
+													}
+												}
+											}
+											numMid <- numMid + 1
+										}
+										numLeft <- numLeft + 1
+									}
+								}
+								if: n > 4 && infold? = 0 && (origops and (_opFold or _opTfold)) > 0 {
+									numSeq <- 1
+									limitSeq <- n - 3
+									while: { numSeq < limitSeq } do: {
+										numFun <- 1
+										limitFun <- n - (2 + numSeq)
+										while: { numFun < limitFun } do: {
+											numStart <- n - (2 + numSeq + numFun)
+											choicesStart <- (allOfSize: numStart inFold?: 1 withOps: ops)
+											choicesFun <- (allOfSize: numFun inFold?: 2 withOps: ops)
+											foreach: (allOfSize: numSeq inFold?: 1 withOps: ops) :idx seqExp {
+												foreach: choicesFun :idx funExp {
+													foreach: choicesStart :idx startExp {
+														if: (origops and _opFold) >  0 {
+															res append: (fold: seqExp with: funExp startingAt: startExp)
+														} else: {
+															mtf <- fold: seqExp with: funExp startingAt: startExp
+															if: (mtf isTfold?) {
+																res append: mtf
+															}
+														}
+													}
+												}
+											}
+											numFun <- numFun + 1
+										}
+										numSeq <- numSeq + 1
+									}
+								}
+							}
+						}
+						res
+					}
+				}
+
+				allOfSize:withOps <- :size strops {
+					ops <- strops fold: 0 with: :acc el {
+						acc or (_names get: el withDefault: 0)
+					}
+					allOfSize: size inFold?: 0 withOps: ops
+				}
+
 				filterTrees <- :trees strops {
 					filtered <- #[]
 					ops <- strops fold: 0 with: :acc el {
@@ -427,7 +551,7 @@
 			}
 			//parser doesn''t currently like vertical whitespace in arays so
 			//this needs to be on a single line until that bug is fixed
-			vals <- #[0u64 1u64 2u64 3u64 4u64 5u64 6u64 7u64 8u64 9u64 10u64 11u64 12u64 13u64 14u64 15u64 0x30001u64 0x50015u64 (lshift: 0x11223344u64 by: 32u64) or 0x55667788u64]
+			vals <- #[0u64 1u64 2u64 3u64 0x30001u64 0x50015u64 (lshift: 0x11223344u64 by: 32u64) or 0x55667788u64]
 			foreach: vals :idx val {
 				print: "p(0x" . (hex: val) . ") = 0x" . (hex: (prog run: val)) . "\n"
 			}
@@ -442,10 +566,20 @@
 			}
 			if: size >= 2 {
 				prog <- program
-				trees <- (prog allOfSize: size)
+				ops <- #[]
 				if: (args length) > 2 {
 					ops <- (args get: 2) splitOn: ","
-					trees <- prog filterTrees: trees ops
+				}
+				trees <- #[]
+				if: (ops length) > 0 {
+					if: size < 9 {
+						trees <- (prog allOfSize: size)
+						trees <- prog filterTrees: trees ops
+					} else: {
+						trees <- (prog allOfSize: size withOps: ops)
+					}
+				} else: {
+					trees <- (prog allOfSize: size)
 				}
 				foreach: trees :idx tree {
 					prog root! tree