我已經實現了一些天真的評估者的一些功能。我剛剛進入了f#的世界,所以它會問你是否存在(如果是,如何實現)一個更快的評估器。我必須得到一個包含(variableName,(condition + newVariableName))的數據結構。這兩個字段是字符串。以下是我評估版本的一部分:最佳性能評估者f#
let env = new Dictionary<_,_>(HashIdentity.Structural)
//eval: expr -> Prop
let rec eval = function
//Val of string -- is a variable name or a string value
| Val e -> if e.Equals("TRUE") then True // True is a Prop type used for BDD Algorithm
elif e.Equals("FALSE") then False // False is a Prop type used for BDD Algorithm
else var e //var of string --- is a Prop type used for BDD Algorithm
| Int i -> var (i.ToString())
| Float e -> var (e.ToString())
| Const c -> var c //Const of string --- is a constant name (ex. "$foo" is a constant)
| Path (e, s) -> var ((eval e).ToString() + "." + s)
| Lookup(s, el) -> var s
| Integer(ex) -> eval ex
| FromTo (e, el) ->var ((eval e).ToString() + (eval el.Head).ToString() + (eval el.Tail.Head).ToString())
| Str(e) -> eval e
| Equality (v, e) -> let evalV = eval v
let evalE = eval e
match evalE with
| Var e ->
let sndKey = "Equality" + evalE.ToString()
if env.ContainsKey (evalV.ToString()) then
if env.[(evalV.ToString())].Equals(sndKey) then
var env.[(evalV.ToString())]
else ~~~ (var env.[(evalV.ToString())])
else
env.Add((evalV.ToString()), (evalV.ToString()) + sndKey)
var ((evalV.ToString()) + sndKey)
| _ as k -> if bddBuilder.Equiv k False then
let sndKey = "Equality" + "False"
if env.ContainsKey (evalV.ToString()) then
if env.[(evalV.ToString())].Equals(sndKey) then
var env.[(evalV.ToString())]
else ~~~ (var env.[(evalV.ToString())])
else
env.Add((evalV.ToString()), (evalV.ToString()) + sndKey)
var ((evalV.ToString()) + sndKey)
else let sndKey = "Equality" + "True"
if env.ContainsKey (evalV.ToString()) then
if env.[(evalV.ToString())].Equals(sndKey) then
var env.[(evalV.ToString())]
else ~~~ (var env.[(evalV.ToString())])
else
env.Add((evalV.ToString()), (evalV.ToString()) + sndKey)
var ((evalV.ToString()) + sndKey)
| Inequality (v, e) -> let evaluatedV = (eval v).ToString()
let evaluatedE = (eval e).ToString()
let sndKey = "Inequality" + evaluatedE
if env.ContainsKey (evaluatedV.ToString()) then
if env.[(evaluatedV.ToString())].Equals(sndKey) then
var env.[(evaluatedV.ToString())]
else ~~~ (var env.[(evaluatedV.ToString())])
else env.Add((evaluatedV.ToString()), (evaluatedV.ToString()) + sndKey)
var ((evaluatedV.ToString()) + sndKey)
| IfThenElse (e1, e2, e3) -> (eval e1 &&& eval e2) ||| ((~~~ (eval e1)) &&& eval e3)
| FindString(e1, e2) -> var ("FS" + (eval e1).ToString() + (eval e2).ToString())
| GreaterThan(e1, e2) -> let evaluatedV = (eval e1).ToString()
let evaluatedE = (eval e2).ToString()
let sndKey = "GreaterThan" + evaluatedE
if env.ContainsKey (evaluatedV.ToString()) then
if env.[(evaluatedV.ToString())].Equals(sndKey) then
var env.[(evaluatedV.ToString())]
else ~~~ (var env.[(evaluatedV.ToString())])
else env.Add((evaluatedV.ToString()), (evaluatedV.ToString()) + sndKey)
var ((evaluatedV.ToString()) + sndKey)
| GreaterThanOrEqual(e1, e2) -> let evaluatedV = (eval e1).ToString()
let evaluatedE = (eval e2).ToString()
let sndKey = "GreaterThanOrEqual" + evaluatedE
if env.ContainsKey (evaluatedV.ToString()) then
if env.[(evaluatedV.ToString())].Equals(sndKey) then
var env.[(evaluatedV.ToString())]
else ~~~ (var env.[(evaluatedV.ToString())])
else env.Add((evaluatedV.ToString()), (evaluatedV.ToString()) + sndKey)
var ((evaluatedV.ToString()) + sndKey)
| Null(e) -> var ("Null" + (eval e).ToString())
| GetToken(e1, e2, e3) -> var ((eval e1).ToString() + (eval e2).ToString())
| Mod(e1, e2) -> var ((eval e1).ToString() + (eval e2).ToString())
| Match(e1, e2) -> let evaluatedV = (eval e1).ToString()
let evaluatedE = (eval e2).ToString()
let sndKey = "Match" + evaluatedE
if env.ContainsKey (evaluatedV.ToString()) then
if env.[(evaluatedV.ToString())].Equals(sndKey) then
var env.[(evaluatedV.ToString())]
else ~~~ (var env.[(evaluatedV.ToString())])
else env.Add((evaluatedV.ToString()), (evaluatedV.ToString()) + sndKey)
var ((evaluatedV.ToString()) + sndKey)
| LessThenOrEqual(e1, e2) -> let evaluatedV = (eval e1).ToString()
let evaluatedE = (eval e2).ToString()
let sndKey = "LessThen" + evaluatedE
if env.ContainsKey (evaluatedV.ToString()) then
if env.[(evaluatedV.ToString())].Equals(sndKey) then
var env.[(evaluatedV.ToString())]
else ~~~ (var env.[(evaluatedV.ToString())])
else env.Add((evaluatedV.ToString()), (evaluatedV.ToString()) + sndKey)
var ((evaluatedV.ToString()) + sndKey)
| LessThen(e1, e2) -> let evaluatedV = (eval e1).ToString()
let evaluatedE = (eval e2).ToString()
let sndKey = "LessThen" + evaluatedE
if env.ContainsKey (evaluatedV.ToString()) then
if env.[(evaluatedV.ToString())].Equals(sndKey) then
var env.[(evaluatedV.ToString())]
else ~~~ (var env.[(evaluatedV.ToString())])
else env.Add((evaluatedV.ToString()), (evaluatedV.ToString()) + sndKey)
var ((evaluatedV.ToString()) + sndKey)
| Length(e) -> var ("Len" + (eval e).ToString())
| Full(e) -> var ("Full" + (eval e).ToString())
| Minus(e1, e2) -> var ((eval e1).ToString() + (eval e2).ToString())
| Times(e1, e2) -> var ((eval e1).ToString() + (eval e2).ToString())
| Plus (e1, e2) -> var ((eval e1).ToString() + (eval e2).ToString())
| Duration(e) -> eval e
| Minutes(e) -> eval e
| Trim(e) -> var ("Tri" + (eval e).ToString())
| Reverse(e) -> var ("Rev" + (eval e).ToString())
| Ast.And (v1, v2) -> eval v1 &&& eval v2
| Ast.Or (v1, v2) -> eval v1 ||| eval v2
| Ast.Not(v1) -> ~~~ (eval v1)
| _ as a-> failwithf "Expression %A not found" a
編輯:此評估器用於驗證布爾條件。在這個版本中,只有一個解釋,這是更好的性能,但我怎麼可以模擬,如以下幾種情況:
- VAR1 ==「foo1」 & & VAR1 ==「foo2的」 --->可滿足:假
- VAR2> = 0 & & VAR2> 0 --->滿足的:真正的
- (!VAR3 == 「foo2的」 & & VAR3 = NULL)|| var3 ==「foo1」 - >可以滿足:true
你可以粘貼表達式的數據結構嗎? – Ankur
另外,它是不是很清楚你的問題到底是什麼...... –
@Tomas - 據我瞭解這個問題,它與評估表達式的策略有關。在代碼中使用字典的問題,並且會有其他方式來評估表達式,而不使用這些字典 – Ankur