domain transformations
TRANSCRIPT
Programming tasks can be
Challenging – unique problems and algorithmsDistinctly average – typical ‘working to spec’ Mind-numbingly boring – obvious stuff , manual
translation
1-to-1 translation from one domain/format to another is boring, wasteful and should (where possible) be automated.
In my case:Math in Word/MathTypeCalculations in Excel
LEVELS OF CHALLENGE
XML-like notation Tags denote mathematical
constructs Special HTML entities used
for mathematical symbolsTwo varieties
Content (uncommon, easier to interpret, constrained)
Presentation (harder to interpret, noisy, much more common)
Supported by Word, MathType, Mathematica, Maple, etc.
<mml:math> <mml:mi>a</mml:mi> <mml:msup> <mml:mi>x</mml:mi> <mml:mn>2</mml:mn> </mml:msup> <mml:mo>+</mml:mo> <mml:mn>2</mml:mn> <mml:mi>x</mml:mi></mml:math>
MATHEMATICAL MARK-UP LANGUAGE
Discriminated union Mutually recursive No tag attributes
Union case contains Constant
Mn(42) String literal
Mi("sin") Expression tuple
e.g. Mfrac(Mn(1),Mn(2))
Expression liste.g. Mtd([…])
type Expression = | Math of Expression list | Menclose of Expression list | Mrow of Expression list | Mi of string | MiNormal of string | Mo of string | Mtd of Expression list | Mtr of Expression list | Mn of string | Mroot of Expression * Expression | Mfrac of Expression * Expression | Msub of Expression * Expression | Msup of Expression * Expression
(etc.)
PARSING MATHML
1. Precompute each union case constructor into a maplet cases = Refl ection.FSharpType.GetUnionCases (typeof<Expression>) |> Array.map(fun f -> (f.Name, Refl ection.FSharpValue.PreComputeUnionConstructor(f))) |> Map.ofArray
2. Parse text as XML Use a preamble to wire up MathML DTDs
3. Try to recursively create each case let ctor = cases.Item name (ctor parameters) :?> Expression For 1..3 parameters, we
Try it as a tuple first; and If failed, try as a list
4. If failed, substitute a 0 (zero) with a comment0 (* sorry, supporting integrals is just too hard *)
PARSING ALGORITHM
42Depends on user
type42.0f (single)42.0 (double)42.0M (decimal)
Attempt to parse eng. notationE.g.
CONSTANT
Mn(42)
𝜋User has to hint if
π is a variable or 3.14Math.PI
Constant calculations not precomputed Math.PI/2.0
User can avoid Greek identifiers rho
SYMBOLS
Mi(“π”)
e, E or ⅇ
Different representationsSome apps use ⅇ
Again, user has to hint if it’s constant
Also, Math.Exp(x)
MORE SYMBOLS!
Mi(<any ‘e’>)
abc No perfect solution
User can hint if vars are all single-letter
May need to inject multiplicationsa*b*c
IMPLIED MULTIPLICATION
Mi(“a”) :: Mi(“b”) :: Mi(“c”)
Mi(“abc”)
𝑥2 , 𝑥𝑛 , 𝑥32We use
_ for subscript__ for superscript
Outputx*xMath.Pow(x, n)x_3__2
SUBSCRIPTS AND SUPERSCRIPTS
Use <msub> and <msup>
𝑎𝑥6+𝑏𝑥3Math.Pow
ineffi cient for integral powers
If power is integralUser can inline up to some threshold x*x*x
Custom function with multiplications My.IntPow(x,8)
POWER INLINING
Msup(Mi(x),Mn(6))
cheaper than pow
reduced by a pow
POWER INLINING IDEAS
sin 2 𝑥MiNormal is
synthetic <mi
mathvariant=normal>
Function tablesMath.Sin
Magic function application operator
Some functions will be missingLeave as-is
FUNCTIONS
Mrow( MiNormal(“sin”) :: Mo() :: Mn(2) :: Mi(“x”))
faster but confusing
speed of div ≈ sqrt
where
Precalculation
Const caches E.g., etc.
Subexpression extraction
POSSIBLE OPTIMIZATIONS
Add, Sub Mul Div,
Sqrt Pow
Discriminated union Much easier code structuring
Pattern matching More concise, constrained switch statement
| "E" | " " | "e" when settings.EIsConstantⅇ Identify complex patterns
| Mo(op) :: (UnitOfMeasureBraces(units) as uu) :: t
Partial/recursive patterns Help us get rid of ‘noise’, e.g. <mrow> let rec (|Simple|_|) = function | SimpleAndPhysical x -> Some x | Mrow(content) -> match content with | Simple h :: [] -> Some h | _ -> None | _ -> None
Custom operators let (<@>) (dictName:Map<_,_>) keyName = if dictName.ContainsKey keyName then dictName.[keyName] else keyName
WHY F#?
The Good
Drastically saves time
Reduces programmer error
Performs optimizations!
The Bad
Easy to break, lots of special cases
Doesn’t support some common constructs, e.g.
RESULTS
Same idea butGot an existing
parser (C#)Better structuredAnalysis in C# (ugly)
More scope>1 available calculation
Web ServicesUI abstraction
Excel
C#, F#NMath
Code Web Svc
C++Boost
iPadapps
AND WHAT OF EXCEL?
THE END
ASK QUESTIONS OR I’LL LEAVE
My domain transformers: MathSharp: http://activemesa.com/mathsharp X2C (Excel to Code) : http://activemesa.com/x2c
Contacts [email protected] @dnesteruk Skype: dmitri.nesteruk