Suppose I have an expression like (actually mine is much more complex, thousands of characters)
expr:a+b*c+b*c*d;
and I want to replace an internal sub-expression with a symbol (useful to avoid recomputation of common subexpressions), say k in place of b*c:
subst(b*c=k,expr);
returns
k+b*c*d+a
How I can make Maxima calculate the "right" substitution so to return (apart from obviuos simplification, here)
k+k*d+a
?
Take a look at let and letsimp. E.g.:
(%i2) expr : a + b*c + b*c*d;
(%o2) b*c*d+b*c+a
(%i3) let (b*c, k);
(%o3) b*c --> k
(%i4) letsimp (expr);
(%o4) d*k+k+a
letsimp differs from subst and tellsimp or defrule in that those other functions make only formal substitutions, i.e., replacing subexpressions which are exactly the same as some pattern.
You can try optimize
http://maxima.sourceforge.net/docs/manual/en/maxima_6.html#IDX219
(%i14) example(optimize);
(%i15) diff(exp(y+x^2)/(y+x),x,2)
2 2 2 2
2 y + x y + x y + x y + x
4 x %e 2 %e 4 x %e 2 %e
(%o15) ------------- + ---------- - ------------ + ----------
y + x y + x 2 3
(y + x) (y + x)
(%i16) optimize(%)
2 y + %2 1
(%o16) block([%1, %2, %3, %4], %1 : y + x, %2 : x , %3 : %e , %4 : --,
%1
4 x %3 2 %3
4 %2 %4 %3 + 2 %4 %3 - ------ + ----)
2 3
%1 %1
Related
I have a function getN' that is supposed to construct a list of n elements recursively, however I think I'm doing something wrong because I can't index into it and the output looks unexpected:
getN' : (Double -> Double -> Double) -> Double -> Double -> Double -> Int -> List Double
getN' f dt t0 y0 0 = []
getN' f dt t0 y0 n = rk4' :: getN' f dt (t0+dt) rk4' (n-1) where
rk4' = rk4 f dt t0 y0
The output of getN' f 0.1 0 1 100 is:
1.0050062486962987 :: getN' f 0.1 0.1 1.0050062486962987 99 : List Double
Which looks unfamiliar to me. Specifically the syntax head::tail is familiar, but Idris usually prints out the entire result in the REPL, which suggests something isn't right in this instance.
The output of index 0 $ getN' f 0.1 0 1 100 is:
(input):1:9:When checking argument ok to function Prelude.List.index:
Can't find a value of type
InBounds 0 (getN' f 0.1 0.0 1.0 100)
What am I doing/getting wrong?
getN' isn't total, so the REPL doesn't evaluate the recursive call (as it could loop forever). Set %default total or total getN' : … to get a warning from the compiler, or check in the REPL with :total getN'. Idris can't reason about Int, and in this particular case, getN' f 0.1 0 1 -1 wouldn't stop.
If you replace Int with Nat it works (with 0 to Z, n to (S n) and n - 1 to n). From another answer: The compiler does only know that subtracting 1 from an Integer results to an Integer, but not which number exactly (unlike when doing it with a Nat). This is because arithmetic with Integer, Int, Double and the various Bits are defined with primary functions like prim__subBigInt.
Why index fails: it needs a proof InBounds k xs, that the list has at least k elements. In Haskell, !! is weaker, and thus can crash at runtime: (getN' f 0.1 0 1 100) !! 101 would compile, but will throw an exception. This can't happen in Idris:
>:t index
Prelude.List.index : (n : Nat) -> (xs : List a) -> {auto ok : InBounds n xs} -> a
>:printdef InBounds
data InBounds : Nat -> List a -> Type where
InFirst : InBounds 0 (x :: xs)
InLater : InBounds k xs -> InBounds (S k) (x :: xs)
auto means, that the compiler tries to search for a proof ok : InBounds n xs. But, again, it doesn't evaluate getN' …, so it doesn't find (or even searches) for a proof. That's the error you are getting: Can't find a value of type InBounds …
I find it really difficult to understand the mechanics of the following recursive function:
sums (x:y:ys) = x:sums(x + y : ys)
sums xs = xs
sums ([0..4])
Output:
[0, 1, 3, 6, 10]
What exactly happens in this line?:
x:sums(x + y : ys)
I would say that before the program can append the 'x' to the list, the function sum(x + y : ys) has to be executed first. But in that case, 'x' would be appended to the list only once - at the end of the recursion loop - which wouldn't result in the given output... so where are the flaws in my logic?
My follow-up question: how should I look at/treat recursive functions in a logical way, that will (hopefully) lead me to an 'aha-erlebnis'?
Any help is much appreciated!
You can understand Haskell code by stepwise reduction. Maybe the following example reduction sequence helps with your aha.
(A Haskell implementation actually does something related to such reduction steps, but maybe in a different order. You get the same end result, though).
In this example, you start with:
sums [0..4]
Expand the [0..4] notation a bit:
sums (0 : 1 : [2..4])
Now we see that the first equation of sums matches, with x = 0, y = 1, and ys = [2..4]. So we get:
0 : sums (0 + 1 : [2..4])
We can compute 0 + 1:
0 : sums (1 : [2..4])
And expand [2..4] a bit:
0 : sums (1 : 2 : [3..4])
Now we see that the first equation of sums matches again, this time with x = 1, y = 2, and ys = [3..4]. So we get:
0 : 1 : sums (1 + 2 : [3..4])
We can compute 1 + 2:
0 : 1 : sums (3 : [3..4])
And expand [3..4] a bit:
0 : 1 : sums (3 : 3 : [4..4])
Now we see that the first equation of sums matches again, this time with x = 3, y = 3, and ys = [4..4]. So we get:
0 : 1 : 3 : sums (3 + 3 : [4..4])
We can compute 3 + 3:
0 : 1 : 3 : sums (6 : [4..4])
And expand [4..4]:
0 : 1 : 3 : sums (6 : 4 : [])
Now we see that the first equation of sums matches again, this time with x = 6, y = 4, and ys = []. So we get:
0 : 1 : 3 : 6 : sums (6 + 4 : [])
We can compute 6 + 4:
0 : 1 : 3 : 6 : sums (10 : [])
This time, the first equation for sums doesn't match. But the second equation matches. So we get:
0 : 1 : 3 : 6 : 10 : []
This is the observed output [0, 1, 3, 6, 10].
This is no different than recursion in any other langauge. When sums [0..4] (the parentheses are unnecessary) is first called, x==0, y==1, and ys == [2..4]. Thus, the return value is a new list created from 0 and sums [1..4].
In a strict language, the recursive call would complete before finally creating the new list. Since Haskell is lazy, a list starting with 0 and continuing with a promise to evaluate sums [1..4] is returned. The recursive call won't actually be evaluated until someone actually tries to access the tail of the list.
You could notice that
sums (x:y:ys) = x:sums(x + y : ys)
is equivalent to
sums (x:y:z:ys) = x:x+y:sums(x+y+z : ys)
sums (x:y:ys) = x:sums(x + y : ys)
and (with more than 2 items) is also equivalent to
sums (x:y:z: w: ys) = x:x+y:x+y+z:sums(x+y+z +w: ys)
sums (x:y:z:ys) = x:x+y:sums(x+y+z : ys)
sums (x:y:ys) = x:sums(x + y : ys)
so by induction you have that
sums(1:2:3:4 :[])
is equal to
1 : 1 + 2 : 1 + 2 + 3 : 1 + 2 + 3 + 4 : []
Based on the above you can also predict that with
fact(x:y:ys) = x: fact(x * y : ys)
fact(xs) = xs
then
fact([1..4])
is
1:1*2:1*2*3:1*2*3*4:[]
There are two equation that define the function sums. Keep rewriting an expression that involves sums using the first equation that matches the argument, or other suitable equations (like 1+2=3).
sums [0..4] =
-- by syntactic sugar
sums (0:1:2:3:4:[]) =
-- by eq. 1, x=0,y=1,ys=2:3:4:[]
0 : sums ((0+1) : 2 : 3:4:[]) =
-- by addition
0 : sums (1 : 2 : 3:4:[]) =
-- by eq. 1, x=1, y=2, ys=3:4:[]
0 : 1 : sums ((1+2) : 3 : 4:[]) =
-- by addition
0 : 1 : sums (3 : 3 : 4:[]) =
-- by eq. 1, x=3, y=3, ys=4:[]
0 : 1 : 3 : sums ((3+3) : 4 : []) =
-- by addition
0 : 1 : 3 : sums (6 : 4 : []) =
-- by eq. 1, x=6, y=4, ys=[]
0 : 1 : 3 : 6 : sums ((6+4):[]) =
-- by addition
0 : 1 : 3 : 6 : sums (10:[]) =
-- by eq 2,xs=(10:[])
0 : 1 : 3 : 6 : 10 : [] =
-- by syntactic sugar
[0,1,3,6,10]
I have this statement:
let val x =
let val x = 5
in(fn y =>(y,x+y))
end
in
let val y=3 and z=10
in x z
end
end;
The output is :
(10,15)
I've been trying to track how this answer was produced but am getting confused. Is there a better way to write this that would help me understand what variables are being used where? Thank you!
First, some alpha-conversion:
let val fnPairOfInputAndInputPlus5 =
let val five = 5
in ( fn input => ( input, five + input ) )
end
in let val ignored = 3 and input = 10
in fnPairOfInputAndInputPlus5 input
end
end;
This code is demonstrating that when you declare a function value, unbound values in the declaring scope, such as the value five, are "enclosed" by the declaration (hence the term "closures"). Thus the function always returns a pair consisting of its input and its input plus five.
You could simplify it to
let fun f y = (y,5+y)
val y=3 and z=10
in
f z
end;
Note that the two instances of y are independent. The inner occurrence of x (which I've eliminated) is independent of the outer one (now renamed f).
Can be understood using manual evaluation with detailed explanations.
Starting with your initial expression:
let val x =
let val x = 5
in (fn y => (y,x + y))
end
in
let val y = 3 and z = 10
in x z
end
end;
Line 2,3,4 is an expression whose type is a function, as you see in the in part. It does not depends on any outer context, so it may be simplified as just fn y => (y, 5 + y), substituting x to 5, according to the binding given in let.
So you now have this:
let val x = fn y => (y, 5 + y)
in
let val y = 3 and z = 10
in x z
end
end;
After substitution of x (and removal of the let which in then now not necessary any more):
let val y = 3 and z = 10
in (fn y => (y, 5 + y)) z
end;
Note the y appearing in (y, 5 + y) are bound to the function's argument, and not to 3. There is no reference to this outer y, so its biding may be removed.
Now you have:
let z = 10
in (fn y => (y, 5 + y)) z
end;
Substituting z to 10 and removing the let which is not necessary any more, you get:
(fn y => (y, 5 + y)) 10;
This is a function application. You may evaluate it, to get:
(10, 5 + 10);
Which gives the final and constant result you noticed:
(10, 15);
I am trying to "parse" a part of LLVM IR. More exactly, from
#.str = private unnamed_addr constant [3 x i8] c"DS\00", section "llvm.metadata"
I want to get "DS". It is the single place in the whole bytecode from where I can get it. I have :
...
Value *VV = cast<Value>(LD100->getOperand(1)->getOperand(0));
errs()<<"\n VV "<<*(VV)<<"\n";
RESULT : VV #.str = private unnamed_addr constant [3 x i8] c"DS\00", section "llvm.metadata"
if(VV->getValueID() == Value::GlobalVariableVal){
GlobalVariable* FD = cast<GlobalVariable>(VV);
Value *VVV = cast<Value>(FD->getOperand(0));
errs()<<"\n VVV "<<*(VVV)<<"\n";
RESULT : VVV [3 x i8] c"DS\00"
if(VVV->getValueID() == Value::ConstantDataArrayVal){
ConstantArray *caa = (ConstantArray *)VVV;
errs()<<"\n "<<(caa->getNumOperands())<<"\n";
errs()<<"\n "<<*(caa->getType())<<"\n";
RESULT : 0
[3 x i8]
}
From this point, I tried to cast to every enum llvm::Value::ValueTy in order to try to iterate through [3 X i8], in order to get "DS" (as a StringRef or std::string would be nice), but I cannot. How I can parse this structure?
Thank you for any help !
Solved it by converting caa to ConstantDataArray and then use getAsString() that gives me exactly "DS".
I am trying to write the following list comprehension in Haskell and it doesn't typecheck. I am new at this and can't really figure out why.
something :: Int -> [Int]
something n = [[ 2 * x + 1 | x <- xs]|xs <- [3..n],i <- [1..],j <-[1..] ,xs == i+j+2*i*j,i<=j,i>=1]
This is what I see:
Couldn't match expected type `Int' with actual type `[t0]'
In the expression: [2 * x + 1 | x <- xs]
NB: There could be a lot more wrong with this piece of code.
Here's what I am really trying to learn to do. From a list of all naturals from 3 to n(which is the Int input to the function), I want to extract just the subset of numbers which can be written as i+j+2*i*j where i, j are integers and the i<=j and i>=1. To this subset list , I want to apply the function 2*x+1 to each element x and output a final list.
Hope that makes sense.
First of all you have a nested list comprehension, so you're creating a list of lists, so the return type should be [[Int]] (list of lists of ints) and not [Int] (list of ints).
Second of all xs is a number (because you take it out of a list of numbers), but its name suggests that it's a list and when you do x <- xs you're actually treating it as if it was a list.
In response to your edit: I don't really see why you thought you needed nested list comprehensions for this. If we just remove the nesting from your code, we get something that is pretty close to working (I've also renamed xs to x because calling a number xs is just confusing - I've also removed the condition that i is at least 1 because that's already a given since you take i from the list [1..]):
[ 2 * x + 1 | x <- [3..n], i <- [1..],j <-[1..] ,x == i+j+2*i*j,i<=j]
Now this compiles, but it will loop forever. Why does it loop forever? Because you take i and j from infinite lists. This means it will start with x=3, i=1, j=1 and then try all values for j from 1 to infinity before it will try the next value of i (so in other words it will never try the next value of i).
So what we need to do is to give i and j upper bounds. An easy upper bound to pick is x (if i or j are greater than x (and neither is smaller than 1), i+j+2*i*j can't possibly be equal to x), so you get:
[ 2 * x + 1 | x <- [3..n], i <- [1..x],j <-[1..x], x == i+j+2*i*j, i<=j]
This works, but it can still be simplified a bit by somewhat: If we take j from the list [i..n] instead of [1..n], we guarantee that j is at least i and we don't need the condition i<=j anymore, so we can write:
[ 2 * x + 1 | x <- [3..n], i <- [1..x], j <-[i..x], x == i+j+2*i*j]
PS: Doing it this way (iterating over all x and then iterating over all possible values of i and j for each x) is a bit inefficient, so you might reconsider your approach. On the other hand if all you need is something that works, this is fine.
First, a function name must not be upper-case.
xs <- [3..n] means that xs is an Int, but x <- xs uses it as a list.
The rest of the comprehension looks a little bit strange, too. If you care to explain what exactly you want to do, we might be able to help a little bit more. :-)
[Edit]
You get an infinite list of your numbers by using [i+j+2*i*j| j <-[2..], i<-[1..(j-1)]], but it's not sorted. [x| x <-[3..(2*n*n)], j <-[2..n], i<-[1..(j-1)], x==i+j+2*i*j] gives a sorted list of all such numbers smaller than 2n².
Let's start with what you've got.
something n = [[ 2 * x + 1 | x <- xs]|xs <- [3..n],i <- [1..],j <-[1..] ,xs == i+j+2*i*j,i<=j,i>=1]
The basic problem here is that you don't need a nested list comprehension.
something n = [ 2 * x + 1 | x <- [3..n], i <- [1..], j <- [1..], x == i+j+2*i*j, i<=j, i>=1]
This will compile. But there is, as you suspect, a lot more wrong with this piece of code.
Let's start with the conditions. Testing for i>=1 is superfluous, given that i <- [1..].
something n = [ 2 * x + 1 | x <- [3..n], i <- [1..], j <- [1..], x == i+j+2*i*j, i<=j]
Similarly, we can get rid of the i<=j condition if we start j off at i instead of at 1.
something n = [ 2 * x + 1 | x <- [3..n], i <- [1..], j <- [i..], x == i+j+2*i*j]
It should be clear that values of j greater than (n - i) `div` (1 + 2 * i) cannot possibly result in an x ≤ n.
something n = [ 2 * x + 1 | x <- [3..n], i <- [1..], j <- [i .. (n - i) `div` (1 + 2 * i)], x == i+j+2*i*j]
Similarly, values of i of n `div` 3 or above cannot possibly result in an x ≤ n.
something n = [ 2 * x + 1 | x <- [3..n], i <- [1 .. (n `div` 3) - 1], j <- [i .. (n - i) `div` (1 + 2 * i)],
x == i+j+2*i*j]
At this point we have done enough for something to actually generate results. But there are duplicate values (e.g. when (i,j) is either (1,7) or (2,4) you get x = 22), which I assume you don't want.
We filter them out using nub from Data.List.
something n = nub [ 2 * x + 1 | x <- [3..n], i <- [1 .. (n `div` 3) - 1],
j <- [i .. (n - i) `div` (1 + 2 * i)], x == i+j+2*i*j]
There's no need to check that x satisfies a condition when we could construct x to satisfy that condition in the first place. (You will want to satisfy yourself that 3 ≤ x ≤ n still.) This is more efficient.
something n = nub [ 2 * x + 1 | i <- [1 .. (n `div` 3) - 1], j <- [1 .. (n - i) `div` (1 + 2 * i)],
let x = i+j+2*i*j]
The results are no longer coming out in ascending order, so let's make sure they do.
something n = sort $ nub [ 2 * x + 1 | i <- [1 .. (n `div` 3) - 1], j <- [1 .. (n - i) `div` (1 + 2 * i)],
let x = i+j+2*i*j]
On a style point, the doubling and adding one is a separate calculation from ensuring that x can be expressed as i+j+2*i*j, so let's split them up.
something n = sort $ map f $ nub [ x | i <- [1 .. (n `div` 3) - 1], j <- [1 .. (n - i) `div` (1 + 2 * i)],
let x = i+j+2*i*j]
where f x = 2 * x + 1
This allows us to get rid of x from the list comprehension.
something n = sort $ map f $ nub [ i+j+2*i*j | i <- [1 .. (n `div` 3) - 1],
j <- [1 .. (n - i) `div` (1 + 2 * i)]]
where f x = 2 * x + 1
Done.