hakaru-dev / hakaru

A probabilistic programming language
BSD 3-Clause "New" or "Revised" License
311 stars 30 forks source link

hygiene bug in expect #14

Closed wrengr closed 8 years ago

wrengr commented 8 years ago

Rob says:

So I have been trying to get normalize to work, and I think I've stumbled onto a bug. I am trying to fix it, so any help or pointers is appreciated.

Suppose you have this simple model:

$> cat docs/examples/quux.hk
x <~ normal(0,1)
y <~ normal(x,2)
return (y,x)

Which you normalize as so:

$> normalize docs/examples/quux.hk
weight(recip(integrate x1 from -∞ to fromProb(∞):
          (exp((negate(((x1 + 0.0) ^ 2)) * 0.5)) *
           1.0 *
           recip(natroot((2.0 * pi), 2)) *
           integrate x0 from -∞ to fromProb(∞):
            (exp((negate(((x0 + negate(x)) ^ 2)) * 0.125)) *
             0.5 *
             recip(natroot((2.0 * pi), 2)) *
             1.0))),
   x <~ normal(0.0, 1.0)
   y <~ normal(x, 2.0)
   return (y, x))

But, negate(x) is the wrong, it is suppose to be negate(x1).

wrengr commented 8 years ago

This is a bug in the Concrete pretty printer. Using the Haskell pretty printer (cf., test6') I get:

(pose (recip
    (integrate negativeInfinity (fromProb infinity) (\ x1 ->
        exp (negate ((x1 + real_ 0) ^ nat_ 2) * real_ (1/2)) *
        prob_ 1 *
        recip (nat_ 2 `thRootOf` (prob_ 2 * pi)) *
        integrate negativeInfinity (fromProb infinity) (\ x0 ->
            exp (negate ((x0 + negate x1) ^ nat_ 2) * real_ (1/8)) *
            prob_ (1/2) *
            recip (nat_ 2 `thRootOf` (prob_ 2 * pi)) *
            prob_ 1)))) $
  (normal (real_ 0) (prob_ 1) >>= \ x1 ->
   normal x1 (prob_ 2) >>= \ x0 ->
   dirac (ann_ ... (pair x0 x1))))
zaxtax commented 8 years ago

No, something is wrong. Here is another program

y0 <~ normal(0,1) y1 <~ normal(y0,1) return (y1,y0)

and with normalize from Pretty/Haskell

(pose (recip (integrate negativeInfinity (fromProb infinity) (\ x1 -> exp (negate ((x1 + real 0) ^ nat 2) * real (1/2)) * prob 1 recip (nat 2 thRootOf (prob 2 * pi)) integrate negativeInfinity (fromProb infinity) (\ x0 -> exp (negate ((x0 + negate y00) ^ nat 2) * real (1/2)) prob_ 1 recip (nat 2 thRootOf (prob 2 * pi)) * prob 1)))) $ (normal (real 0) (prob 1) >>= \ y00 -> normal y00 (prob 1) >>= \ y11 -> dirac (ann_ (SData (STyApp (STyApp (STyCon (SingSymbol Proxy :: Sing "Pair")) SReal) SReal) (SPlus (SEt (SKonst SReal) (SEt (SKonst SReal) SDone)) SVoid)) ((pair y11 y00)))))

That y00 should be x1. This is not a Concrete bug.

On Thu, Mar 24, 2016 at 7:49 PM, wren romano notifications@github.com wrote:

This is a bug in the Concrete pretty printer. Using the Haskell pretty printer (cf., test6') I get:

(pose (recip (integrate negativeInfinity (fromProb infinity) (\ x1 -> exp (negate ((x1 + real 0) ^ nat 2) * real (1/2)) * prob 1 recip (nat 2 thRootOf (prob 2 * pi)) integrate negativeInfinity (fromProb infinity) (\ x0 -> exp (negate ((x0 + negate x1) ^ nat 2) * real (1/8)) prob_ (1/2) recip (nat 2 thRootOf (prob 2 * pi)) * prob 1)))) $ (normal (real 0) (prob 1) >>= \ x1 -> normal x1 (prob 2) >>= \ x0 -> dirac (ann_ ... (pair x0 x1))))

— You are receiving this because you are subscribed to this thread. Reply to this email directly or view it on GitHub https://github.com/hakaru-dev/hakaru/issues/14#issuecomment-201076152

wrengr commented 8 years ago

added test6b which actually triggers the bug without going through the commandline interface, parsers, pretty printers, etc

wrengr commented 8 years ago

Should be fixed by commit 61e5117

wrengr commented 8 years ago

Is definitely fixed by commit c9641a9

$> cat ./bugs/bug14.hk
x <~ normal(0,1)
y <~ normal(x,2)
return (y,x)
$> cat ./bugs/bug14.hk | ./dist/build/normalize/normalize
weight(recip(integrate x2 from -∞ to fromProb(∞):
              (exp((negate(((x2 + 0.0) ^ 2)) * 0.5)) *
               1.0 *
               recip(natroot((2.0 * pi), 2)) *
               integrate x3 from -∞ to fromProb(∞):
                (exp((negate(((x3 + negate(x2)) ^ 2)) * 0.125)) *
                 0.5 *
                 recip(natroot((2.0 * pi), 2)) *
                 x0 = (x3, x2)
                 1.0))),
       x <~ normal(0.0, 1.0)
       y <~ normal(x, 2.0)
       return (y, x))