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


Sponsored



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_ao6uuBDUTnh2dWxYMWdhZWc/view?usp=sharing
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

  1. create the list of all possible combinations on true and false of length 3
  2. print out the combinations and the result of applying expr to that combination
  3. 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.