Android Question RegEx help for logic expressions evaluation

giggetto71

Active Member
Licensed User
Longtime User
Hi,
I am trying to reproduce a functionality I had many years ago in VB old program. basically, there, I had some expression written by the user involving some logic expression. the syntax for the user was something like:

"{Var1} <> 3 AND ({Var2} <5 OR {Var2} > 8)"

in the code I was looking for all the variables name inside {} and replace them with some values from a database, so for example if Var1 was 2 and Var2 was 4 , I could create at runtime the variable

"2 <> 3 AND (4 < 5 OR 4>8)"

at this point I was doing:

B4X:
Set EvalEng = CreateObject("ScriptControl")
EvalEng.Language = "VBScript" 'JavaScript was another option
txt = ReplacedUserText 'in the example above "2<>3 AND (4<5 OR 4>8)"
Result = EvalEng.Eval(txt)

I am pretty sure there is somenthing like that in B4X but I could not find it. I would assume it should be in the RegEx but I need some guidance.
Can sameone help?
thanks!
 

giggetto71

Active Member
Licensed User
Longtime User
that's for sure sorry maybe I did not explicity wrote that the replace part was given....what I am missing is the evaluation part..
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
Although B4X does not have a logic evaluator, you can use the arithmetic evaluator provided by @Erel.

https://www.b4x.com/android/forum/threads/b4x-eval-expressions-evaluator.54629/

You have to use a little ingenuity and knowledge https://en.wikipedia.org/wiki/Boolean_algebra

Here is a start, (e.Eval is in the example posted by @Erel):

B4X:
    Dim a As Int = 3
    Dim b As Int = 5
    Dim c As Int = -1

    Dim logic1 As Int = IIf(a < b, 1, 0)
    Dim logic2 As Int = IIf(c > 0, 1, 0)
    
    Log(LogicalEval($"${logic1} OR ${logic2}"$))
B4X:
Sub LogicalEval(s As String) As Boolean
    Dim result As Int
    s = s.Replace("OR", "+").Replace("AND", "*")
    result = e.Eval(s)
    Return result > 0
End Sub
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
July 1 is our national holiday, happy Canada Day!
I have modified the routine by @Erel to handle comparator operators.

B4X:
Sub Process_Globals
    Dim e As B4XLogicalEval
End Sub

Sub AppStart (Args() As String)
    e.Initialize(Me, "Eval")
    Log(LogicalEval("(a <> b) OR ((c < 0) AND (d > 0))", CreateMap("a": 3, "b": 5, "c": -1, "d": 52)))
End Sub

Sub LogicalEval(s As String, substitutions As Map) As Boolean
    For Each kw As String In substitutions.keys
        s = s.Replace(kw, substitutions.Get(kw))
    Next
    Return e.Eval(s.Replace(" OR ", "+").Replace(" AND ", "*").Replace("~", "-")) > 0
End Sub

Note: "~" is the unary NOT operator.
Note: AND and OR need to be surrounded by blanks.
 

Attachments

  • LogicalEvaluator.zip
    3 KB · Views: 152
Upvote 0

giggetto71

Active Member
Licensed User
Longtime User
@William Lancee thank you very much! this is very close to what I am looking for. I am just not sure I got how to use the not operator.
I tried

Log(LogicalEval(" ~ (a = 1)",CreateMap("a":8)))

and I expected "true" as NOT (a = 1) should give NOT False -> True, while I get "false"

same for

Log(LogicalEval(" ~ (a < 1)",CreateMap("a":8)))

I would expect True as a is NOT < 1..

Am I using the wrong syntax for the NOT?
thanks
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
You're right, the ~ does not work as is. By replacing it with "-" it multiples the result by -1.
I'll work on a solution.
 
Upvote 0

William Lancee

Well-Known Member
Licensed User
Longtime User
Please test the attached V2. I kept the ~ as NOT and added it as an operator in the class.
 

Attachments

  • logicEvaluator_V2.zip
    3.1 KB · Views: 151
Upvote 0
Top