rw expression IN expression - lean

Say, I need:
rw ← nat.mul_one (d+d),
But there are multiple (d+d) in the whole goal. Can I do something like:
rw ← nat.mul_one (d+d) in (5+(d+d)),
so that (d+d) is rewritten only where the full expression in parentheses is 5+(d+d) is matched?

You can try mathlib's nth_rewrite, or rw's optional occs argument. For example:
if ⊢ (d + d) + 5 * (d + d) + 2 * (d + d) = 8 * (d + d), then nth_rewrite ←nat.mul_one (d + d) 1 should work, as should rw ←nat.mul_one (d + d) { occs := occurrences.pos [2]} (note that nth_rewrite is zero-indexed whilst rw is 1-indexed).
You can also mess around with conv, but I don't recommend that; something that would work for the above example with conv is conv { congr, congr, congr, skip, rw ←nat.mul_one (d + d) }.

You can either learn about the joys of conv mode here, which enable you to do targetted rewriting, or you can use the nth_rewrite tactic documented here which will let you choose precisely which of the d+ds you want to change.

Related

Add brackets to an expression with regex

I want to add parentheses to parts of an expression.
The parts are any multiplied expressions that are NOT in parentheses.
For example, change:
a * b + c + d * e * f + g
to:
(a * b)+ c +( d * e * f) + g
another example, change:
(a1+b1) + ( c1 * d1) + e1 * f1 *g1 * h1 + J1
to:
(a1+b1) + ( c1 * d1) + (e1 * f1 *g1 * h1) + J1
The only elements in the expression to check will be * + ( ) and variable names with no spaces, like a1 f1 p3 etc.
I came up with something but it shows the expressions WITH brackets. I want the opposite of that.
This is what I have:
Function testParen()
Dim cText As String, cPattern As String
Dim itemFound As Variant, nItems
Dim getParen As New RegExp
getParen.Global = True
getParen.IgnoreCase = True
cText = "(a1*q1) + (b1*c1) + d1*e1*f1 * (g1+h1) + (k1*m1) "
cPattern = "(^|[^*])\(([^()]+)\)"
'cPattern = "\("
getParen.Pattern = cPattern
cText = Replace(cText, " ", "")
Dim mc As MatchCollection
Set mc = getParen.Execute(cText)
nItems = mc.Count
'Debug.Print vbNewLine
If nItems > 0 Then
Debug.Print nItems
For Each itemFound In mc
Debug.Print Replace(itemFound, "+", "")
Next
Else
Debug.Print "No items"
End If
End Function
I recommend you rethink your approach and parse the expression properly rather than just inserting parentheses. Perhaps initially splitting on + would be simpler, rather than using a regex that you don't fully understand and can't confidently adjust.
Anyway, here is an example in JavaScript of the kind of regex that could be used. I will leave any conversion to VBA to you.
const rx = /(\+\s*|^\s*)((?:\s*\w+\s*\*)+\s*\w+)(?=\s*\+|\s*$)/g;
const expression = '(a1+b1) + ( c1 * d1) + e1 * f1 * g1 * h1 + J1';
console.log(expression.replace(rx, '$1($2)'));
Note that the above has not been properly tested and may be brittle. I am not going to try and explain it, but you could enter the regex into for example https://regex101.com/ if you want a breakdown of how it works.
In the regex, the first \+ could be replaced with for example [^(\s\w] and the second \+ with [^)\s\w], if for example you want - to work also.

Sympy substitute in fractions won't work as expected

Simpy is not detecting basic substitions with subs.
I have the following fraction:
d₂⋅n₁⋅n₂
──────── + m₂⋅n₁ + mm₂⋅n₂
nc
─────────────────────────
nc
Written as
cm2 = (d2*n1*n2/nc + m2*n1 + mm2*n2)/nc
Now I want to replace n1/nc = np1 and n2/nc = np2. So I've written:
cm2.subs({n1/nc : symbols("np1"), n2/nc: symbols("np2")})
The result is:
d₂⋅n1p⋅n₂ + m₂⋅n₁ + mm₂⋅n₂
──────────────────────────
nc
Instead I expected that sympy would figure out the other substitutions and output:
d2⋅n1p⋅n2p + m2⋅n1p + mm2⋅n2p
What I'm missing here?
subs is mostly literal, so after the first substitution, say n1/nc->n1p, then n2/nc no longer appears and so it cannot be replaced. But it's not necessary to do the re-arrangement of expressions to get them in the form needed to make the substitution, you can use solve to resolve everything for you:
>>> eqs
(Eq(cm2, (d2*n1*n2/nc + m2*n1 + mm2*n2)/nc), Eq(n1/nc, np1), Eq(n2/nc, np2))
>>> solve(eqs,cm2,n1,n2, dict=True)
[{cm2: d2*np1*np2 + m2*np1 + mm2*np2, n1: nc*np1, n2: nc*np2}]
There is also an unimplemented feature described here that offers, perhaps, a more intuitive way of doing this.
Sympy's subs can have troubles converting an expression by another expression, especially if they don't appear literally in the source expression. It also can be quite ambiguous.
When the goal is that all n1 and n2 disappear from cm2, the substitution can be written differently:
from sympy import symbols
d2, n1, n2, nc, m2, mm2, n = symbols("d2 n1 n2 nc m2 mm2 n")
np1, np2 = symbols("np1 np2")
cm2 = (d2 * n1 * n2 / nc + m2 * n1 + mm2 * n2) / nc
cm2.subs({n1: np1 * nc, n2: np2 * nc}).simplify()
Result: d2*np1*np2 + m2*np1 + mm2*np2

Recursive sequence in VBA

I want to write a function which has 5 inputs :
which outputs
:
Problem seems very simple for me, however I'm dealing with error :
Function Sequence(x_0 As Double, x_1 As Double, a As Double, b As Double, n As Double) As Double
If n = 0 Then
x_0
ElseIf n = 1 Then
x_1
Else
a * Sequence(x_0, x_1, a, b, n-1) + b * Sequence(x_0, x_1, a, b, n-2)
End If
End Function
And If I want to use my function :
Sequence(1;1;1;1;1)
I see error :
Do you hany idea what I'm doing wrong ?
In VBA, the function to call parameters must be separated by comma. Like a UDF function you can call it from sheet using the list separator according to regional settings ["=Sequence(1, 1, 1, 1, 1) or Sequence(1; 1; 1; 1; 1)];
If a called function returns something, the way you call it should be in a way to deal with the returned value:
Debug.Print Sequence(1, 1, 1, 1, 1)
Then, try playing with the function parameters.
When there are some conditional function outputs, your function must be configured to return:
Function Sequence(x_0 As Double, x_1 As Double, a As Double, b As Double, n As Double) As Double
If n = 0 Then
Sequence = x_0
ElseIf n = 1 Then
Sequence = x_1
Else
Sequence = a * Sequence(x_0, x_1, a, b, n - 1) + b * Sequence(x_0, x_1, a, b, n - 2)
End If
End Function

How to convert postfix expression in the form of a string into infix in c++ without using parenthesis?

There is a postfix expression in the form of string for e.g: ab+cd+* , so the output should be a * c + a * d + b * c + b * d (as we cannot write (a+b)*(c+d) because parenthesis are not allowed.)

VBA - Check whether a parameter is set using the bit key

i have a dialog with a few parameters (arround 20).
Every parameter gets a value like 1,2,4,8,16,32 and so on.
By closing dialog an integer will be set with the sum of the parameter like 2+8+16+64.
Now i have a few options to run my program.
For example:
The first option needs to run the parameter 2,8 and 16 so i need to check if 2,8 and 16 will be checked in my integer.
I know that there is a way but not really how.
Maybe u can help.
Thanks
Jassin
The first option need
Apply the And operator on a mask (m, interesting bits set) and your data (d, e). If the result is equal to m, then all the bits set in m are set in the data.
>> d = 4 + 2 + 1
>> e = 4 + 1
>> m = 4 + 2 + 1
>> WScript.Echo 0, CStr(m = (d And m))
>> WScript.Echo 1, CStr(m = (e And m))
>>
0 True
1 False

Resources