Hi,

Please find code attached. Please CC me on replies as I'm not
subscribed. I would have added this via trac but couldn't log in (was
endlessly prompted for username/password and guest/guest didn't make it
go away).

This is to do with strictness modifiers: if you remove all the ! from
the code then the bug vanishes.

Also, the following works fine:

buildOctTree (Vec 0 0 0) 10 10 10 [(a,(Vec a a a)) | a <- [(-4.0),(-2.0)..4.0]]

Also, having done that, the problematic expressions work fine - the bug
only appears if the expression below is run as the first call to
buildOctTree in the ghci session.

This is on a P4, 2GB RAM, Debian unstable, ghc 6.6 (both hand rolled and
from debian).

uname -a =
   Linux smudge 2.6.18-2-686 #1 SMP Wed Nov 8 19:52:12 UTC 2006 i686 GNU/Linux

> ghci -v OctTree
   ___         ___ _
  / _ \ /\  /\/ __(_)
 / /_\// /_/ / /  | |      GHC Interactive, version 6.6, for Haskell 98.
/ /_\\/ __  / /___| |      http://www.haskell.org/ghc/
\____/\/ /_/\____/|_|      Type :? for help.

Using package config file: /usr/lib/ghc-6.6/package.conf
wired-in package base mapped to base-2.0
wired-in package rts mapped to rts-1.0
wired-in package haskell98 mapped to haskell98-1.0
wired-in package template-haskell mapped to template-haskell-2.0
Hsc static flags: -static
Loading package base ... linking ... done.
*** Parser:
*** Desugar:
*** Simplify:
*** CorePrep:
*** ByteCodeGen:
*** Parser:
*** Desugar:
*** Simplify:
*** CorePrep:
*** ByteCodeGen:
*** Chasing dependencies:
Stable obj: []
Stable BCO: []
unload: retaining objs []
unload: retaining bcos []
Upsweep completely successful.
*** Deleting temp files:
Deleting: 
*** Chasing dependencies:
Stable obj: []
Stable BCO: []
unload: retaining objs []
unload: retaining bcos []
compile: input file OctTree.hs
*** Checking old interface for main:OctTree:
[1 of 1] Compiling OctTree          ( OctTree.hs, interpreted )
*** Parser:
*** Renamer/typechecker:
*** Desugar:
    Result size = 1587
*** Simplify:
    Result size = 2390
    Result size = 2137
    Result size = 2105
    Result size = 2100
*** Tidy Core:
    Result size = 2198
*** CorePrep:
    Result size = 2646
*** ByteCodeGen:
*** Deleting temp files:
Deleting: 
Upsweep completely successful.
*** Deleting temp files:
Deleting: 
Ok, modules loaded: OctTree.
*OctTree> buildOctTree (Vec 0 0 0) 10 10 10 [(a,(Vec a a a)) | a <- 
[(-4.0),(-3.9)..4.0]]
*** Parser:
*** Desugar:
*** Simplify:
*** CorePrep:
*** ByteCodeGen:
<interactive>: internal error: interpretBCO: unknown or unimplemented opcode 
20196
    (GHC version 6.6 for i386_unknown_linux)
    Please report this as a GHC bug:  http://www.haskell.org/ghc/reportabug
Aborted

Matthew
-- 
Matthew Sackman
http://www.wellquite.org/
{-
 - OctTrees.hs: Implementation of OctTrees in Haskell
 - Copyright (C) 2006  Matthew Sackman
 -
 - This program is free software; you can redistribute it and/or
 - modify it under the terms of the GNU General Public License
 - as published by the Free Software Foundation; version 2
 - of the License only.
 - 
 - This program is distributed in the hope that it will be useful,
 - but WITHOUT ANY WARRANTY; without even the implied warranty of
 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 - GNU General Public License for more details.
 - 
 - You should have received a copy of the GNU General Public License
 - along with this program; if not, write to the Free Software
 - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 -}

module OctTree
    (OctTree,
     buildOctTree,
     findInRadius
    )
    where

import Data.List

data Vector = Vec  !Double  !Double  !Double
                  deriving (Show, Eq)

findDisplacement :: Vector -> Vector -> (Double, Vector)
findDisplacement (Vec ax ay az) (Vec bx by bz) =
    (len, Vec dx dy dz)
    where
      len = sqrt ((dx*dx) + (dy*dy) + (dz*dz))
      dx = (bx - ax)
      dy = (by - ay)
      dz = (bz - az)

--                           lne     usw
data OctTree value = OctTree !Vector !Vector !(OctTreeNode value)
                     deriving (Show)

data OctTreeNode value = EmptyLeaf
--                            pos     value
                       | Leaf !Vector !(value)
                       | Node
--                       lne              lse              lsw              lnw
                         !(OctTree value) !(OctTree value) !(OctTree value) !(OctTree value)
--                       unw              usw              use              une
                         !(OctTree value) !(OctTree value) !(OctTree value) !(OctTree value)
                         deriving (Show)

buildOctTree :: (Show a) => Vector -> Double -> Double -> Double -> [(a,Vector)] -> (OctTree a)
buildOctTree (Vec mx my mz) x_size y_size z_size values = foldl' (\t (v,pos) -> insertValue t v pos) initial values
    where
      initial = OctTree (Vec (mx+x) (my+y) (mz-z)) (Vec (mx-x) (my-y) (mz+z)) EmptyLeaf
      x = x_size /2
      y = y_size /2
      z = z_size /2

insertValue :: (Show a) => (OctTree a) -> a -> Vector -> (OctTree a)
insertValue (OctTree lnePos uswPos EmptyLeaf) value pos = OctTree lnePos uswPos (Leaf pos value)
insertValue (OctTree lnePos@(Vec lne_x lne_y lne_z) uswPos@(Vec usw_x usw_y usw_z) (Leaf pos1 v1)) v2 pos2 = n3
    where
      n1 = OctTree lnePos uswPos (Node lne lse lsw lnw unw usw use une)
      n2 = insertValue n1 v1 pos1
      n3 = insertValue n2 v2 pos2
      middle@(Vec mx my mz) = (Vec ((lne_x + usw_x)/2) ((lne_y + usw_y)/2) ((lne_z + usw_z)/2))
      lne = OctTree lnePos middle EmptyLeaf
      lse = OctTree (Vec lne_x my lne_z) (Vec mx usw_y mz) EmptyLeaf
      lsw = OctTree (Vec mx my lne_z) (Vec usw_x usw_y mz) EmptyLeaf
      lnw = OctTree (Vec mx lne_y lne_z) (Vec usw_x my mz) EmptyLeaf
      unw = OctTree (Vec mx lne_y mz) (Vec usw_x my usw_z) EmptyLeaf
      usw = OctTree middle uswPos EmptyLeaf
      use = OctTree (Vec lne_x my mz) (Vec mx usw_y usw_z) EmptyLeaf
      une = OctTree (Vec lne_x lne_y mz) (Vec mx my usw_z) EmptyLeaf
insertValue n@(OctTree lnePos uswPos (Node lne lse lsw lnw unw usw use une))
            value pos = OctTree lnePos uswPos node
    where
      node =
          case inQuadrant lne pos of
            True -> (Node (insertValue lne value pos) lse lsw lnw unw usw use une)
            False -> case inQuadrant lse pos of
                       True -> (Node lne (insertValue lse value pos) lsw lnw unw usw use une)
                       False -> case inQuadrant lsw pos of
                                  True -> (Node lne lse (insertValue lsw value pos) lnw unw usw use une)
                                  False -> case inQuadrant lnw pos of
                                             True -> (Node lne lse lsw (insertValue lnw value pos) unw usw use une)
                                             False -> case inQuadrant unw pos of
                                                        True -> (Node lne lse lsw lnw (insertValue unw value pos) usw use une)
                                                        False -> case inQuadrant usw pos of
                                                                   True -> (Node lne lse lsw lnw unw (insertValue usw value pos) use une)
                                                                   False -> case inQuadrant use pos of
                                                                              True -> (Node lne lse lsw lnw unw usw (insertValue use value pos) une)
                                                                              False -> case inQuadrant une pos of
                                                                                         True -> (Node lne lse lsw lnw unw usw use (insertValue une value pos))
                                                                                         False -> error $ "Value " ++ (show value) ++ " at position " ++ (show pos) ++ " is not in node " ++ (show n)
                                                                            
inQuadrant :: (OctTree a) -> Vector -> Bool
inQuadrant (OctTree (Vec lne_x lne_y lne_z) (Vec usw_x usw_y usw_z) _) (Vec x y z) =
    (x > usw_x) && (y > usw_y) && (z < usw_z) && (x <= lne_x) && (y <= lne_y) && (z >= lne_z)

findInRadius :: OctTree a -> Vector -> Double -> [(a,Vector,Double)]
findInRadius (OctTree _ _ EmptyLeaf) _ _ = []
findInRadius (OctTree _ _ (Leaf vPos value)) from radius =
    case dist <= radius of
      True -> [(value, vPos, dist)]
      False -> []
    where
      (dist,_) = findDisplacement from vPos
findInRadius (OctTree _ _ (Node lne lse lsw lnw unw usw use une)) from@(Vec fx fy fz) radius =
    concat result
    where
      children = filter findInRadius' [lne, lse, lsw, lnw, unw, usw, use, une]
      result = map (\n -> findInRadius n from radius) children
      findInRadius' :: OctTree a -> Bool
      findInRadius' (OctTree _ _ EmptyLeaf) = False
      findInRadius' (OctTree (Vec lne_x lne_y lne_z) (Vec usw_x usw_y usw_z) _) =
          ((fx + radius) > usw_x) && ((fx - radius) <= lne_x) &&
          ((fy + radius) > usw_y) && ((fy - radius) <= lne_y) &&
          ((fz - radius) < usw_z) && ((fz + radius) >= lne_z)
_______________________________________________
Glasgow-haskell-bugs mailing list
Glasgow-haskell-bugs@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-bugs

Reply via email to