Question
Map to new space on Thu, 25 Feb 2016 10:18:14
no readable content in debug
it can not out of loop
values |> Seq.iter(fun bs -> printfn "%s %b" (bs |> toString)(expr bs)) values |> Seq.iter(fun bs -> v.Add(expr bs))
type exprintlogic = | Integers of int | Conj of exprintlogic * exprintlogic | Disj of exprintlogic * exprintlogic | Equal of exprintlogic * exprintlogic | Impl of exprintlogic * exprintlogic | Neg of exprintlogic | Xaa | Xbb | Xcc with static member ( + ) (f, g) = Disj(f, g) static member ( * ) (f, g) = Conj(f, g) let tablen n expr = let replicate n xs = let rec repl acc n = match n with | 0 -> acc | n -> let acc' = acc |> List.collect(fun ys -> xs |> List.map(fun x -> x :: ys)) repl acc' (n-1) repl [[]] n let values = replicate n [true; false] let toString bs = System.String.Join(" ", Array.ofList (bs |> List.map string)) let v = new List<Boolean>() try values |> Seq.iter(fun bs -> printfn "%s %b" (bs |> toString)(expr bs)) values |> Seq.iter(fun bs -> v.Add(expr bs)) with ex -> Console.Write(ex.Message.ToString()) v let ValidateAxiomWith3Variables(ls) = let xx = tablen 3 (fun [a; b; c] -> (expr2boolean3 ls a b c) ) //let xx = tablen 2 (fun [a; b] -> (expr2boolean2 ls a b) ) let mutable result = true for i in xx do if i.Equals(false) then result <- false result let result2 = Conj(Disj(Neg(Integers(2)),Integers(1)),Conj(Integers(2),Integers(1))) let result1 = Disj(Neg(Integers(3)),Integers(2)) let xx = ValidateAxiomWith3Variables(Disj(Neg(result2),result1))
New
Replies
Mr. Tines on Thu, 25 Feb 2016 19:17:10
Your question is unclear.
This code
let mutable result = true for i in xx do if i.Equals(false) then result <- false result
is more idiomatically written
Seq.forall id xx
Also with .net 4 you can write
let toString bs = System.String.Join(" ", bs |> List.map string)
I'm assuming that expr2boolean3 is some arbitrary ternary operation, because if I define
let expr2boolean3 ls a b c = true;;
the program quite happily outputs
True True True true False True True true True False True true False False True true True True False true False True False true True False False true False False False true val xx : bool = true
Mr. Tines on Thu, 25 Feb 2016 20:06:02
And the problematic piece of code would be better written as
let transform bs = let result = expr bs printfn "%s %b" (toString bs) result result values |> Seq.map transform
where you will be able to break in the transform function. You won't get the "truncate on exception" behaviour, but that seems rather bizarre error handling anyway
Map to new space on Fri, 26 Feb 2016 05:11:43
i use last post's code,
it can not pause at break point in VS2010
https://drive.google.com/file/d/0Bxs_ao6uuBDUWW9qSS1lSjZPMms/view?usp=sharing
New
Mr. Tines on Fri, 26 Feb 2016 19:40:58
Expressions like
values |> Seq.map transform
are lazy, exactly like LINQ expressions in C#. They don't get executed where you write them, but where you use the results.
So in this variant
let tablen n expr = let replicate n xs = let rec repl acc n = match n with | 0 -> acc | n -> let acc' = acc |> List.collect(fun ys -> xs |> List.map(fun x -> x :: ys)) repl acc' (n-1) repl [[]] n let values = replicate n [true; false] let toString bs = System.String.Join(" ", bs |> List.map string) try let transform bs = let result = expr bs // Breakpoint printfn "%s %b" (toString bs) result result values |> Seq.map transform // 1 with ex -> Console.Write(ex.Message.ToString()) Seq.empty<Boolean> let expr2boolean3 ls a b c = true let ValidateAxiomWith3Variables(ls) = let xx = tablen 3 (fun [a; b; c] -> (expr2boolean3 ls a b c) ) let mutable result = true for i in xx do // 2 if i.Equals(false) then result <- false result
the breakpoint at
// Breakpoint
isn't hit when you step on from // 1; it's hit when you step on from // 2; and if you rewrite the latter function in the more idiomatic form
let ValidateAxiomWith3Variables(ls) = let xx = tablen 3 (fun [a; b; c] -> (expr2boolean3 ls a b c) ) Seq.forall id xx // 3
or even
let ValidateAxiomWith3Variables(ls) = tablen 3 (fun [a; b; c] -> (expr2boolean3 ls a b c) ) |> Seq.forall id // 3
then you hit the breakpoint only as you step out of the function at // 3
In the version of the program you showed in the video,
you discard these sequences unevaluated, so don't get the side-effects (including hitting breakpoints, as well as the more obvious printing or adding to the mutable List) you were looking for.
Going back to the original program, if you split the lambdas across more than one line
values |> Seq.iter(fun bs -> printfn "%s %b" (bs |> toString)(expr bs)) // Breakpoint values |> Seq.iter(fun bs -> v.Add(expr bs))then you can apply a breakpoint as shown, and stepping down tablen will show it hitting the breakpoint many times.
Map to new space on Thu, 03 Mar 2016 08:32:19
i tried this code and another method to open a new line, still can not break into it
try let transform bs = let result = expr bs // Breakpoint printfn "%s %b" (toString bs) result result values |> Seq.map transform // 1 with ex -> Console.Write(ex.Message.ToString()) Seq.empty<Boolean>
https://drive.google.com/file/d/0Bxs_ao6uuBDUUjlLdDJDOWszNVU/view?usp=sharing
Mr. Tines on Thu, 03 Mar 2016 20:04:20
Let's look at what the function tablen is trying to do. It's supposed to
- create the list of all possible combinations on true and false of length 3
- print out the combinations and the result of applying expr to that combination
- return a sequence of all the results of applying expr to each combination in turn.
Setting aside part 2 that boils down to
replicate n [true; false] |> Seq.map expr
with no need for any auxiliary variables to hold the result.
Step 2 just complicates the function we map over, so that it prints as the value goes past.
In the first video, you create the lazy sequence values
values |> Seq.map transform1
and
values |> Seq.map transform2
but never do anything with them, so the values go out of scope unexercised.
The difference between our examples in this case is that my version returns that value, which is then iterated over in the calling code; your version returns the entirely pointless List<bool> called v, which is empty at that point because the iteration over the second map operation has not happened (and never will, thereafter).
I'm not sure what is going on in the second video, as I would have expected the console to be showing lines like
True True True true True True True true False True True true True False True true False False True true True True False true False True False true True False False true False False False true
as you step through the first expression, not the spaced apart lines with just *** on them. Also, whatever you were doing with the Watch window was lost off the bottom of the screen.
With this code
values |> Seq.iter(fun bs -> printfn "%s %b" (bs |> toString)(expr bs)) // A values |> Seq.iter(fun bs -> v.Add(expr bs)) //B
I hit a breakpoint set on the line // A 24 times (three times per element) and a breakpoint set on // B 8 times.
You could of course just write
values |> Seq.iter(fun bs -> let r = expr bs printfn "%s %b" (toString bs) r v.Add(r)) //C
rather than iterating and evaluating expr over every item twice. When I execute that case I hit a breakpoint on // C 8 times.
Map to new space on Mon, 14 Mar 2016 02:33:44
i succeed to see with for loop
and discover that vv is null
why vv is null? where is vv's value?
in for vv in values do
values have value, but vv is null, it is quite odd
other case have vv null too, but other case do not loop forever
and can be out of loop finally, but when i hard code the case, it can not be out of loop
where is the problem?
updated second video due to first video rotation problem and reinstall VLC again
https://drive.google.com/file/d/0Bxs_ao6uuBDUOFJjUkwxX0N2akE/view?usp=sharing
New
Mr. Tines on Mon, 14 Mar 2016 23:12:42
It looks like you are having conceptual difficulty with lazy expressions and are relapsing to the imperative comfort zone once more there, with the `for` loops.
From the video, it seems the name vv is not assigned while the program is evaluating the expression
printfn "%s %b"
in which it does not occur, but is assigned as soon as you step on to
(vv |> toString)
and will be updated at that point on the next iteration.
Map to new space on Tue, 15 Mar 2016 08:06:02
after spend more time to debug this at home, i succeed to find the source of error
it is in
expr2boolean3
missing 3 cases
Integer(a) -> a
Integer(b) -> b
Integer(c) -> c
the method i use to debug is
for ii in 1..values.length do
let vv = values.[ii]
force it to show correct value in watch to ensure it show value
then i discover forever loop at
expr bs
which is calling upper function,
expr2boolean3
thanks to this bug, force me to think and invent another method to solve another problem.
i go back to use this my old program, because my new method is not perfect, i need this program to check whether scheme is changed.
Of course, there is still things to think new again.