%export net node choices short_description short_descriptions
        navigate final_state shownavigate showfinalstate
        show_annotated_navigate show_annotated_final_state
node == int
int == num

choices == [node]
net == node -> choices


probability == real
real == num
state == [(node, probability)]
trace == [state]







navigate :: net -> node -> trace
  navigate n start = iterate (transition n) [(start, 1)]

final_state :: net -> node -> state
  final_state n start = limit (navigate n start)








transition :: net -> state -> state
  transition n s = merge_cases (concat (map (case_transition n) s))

case_transition :: net -> (node, probability) -> [(node, probability)]
  case_transition n (here, p) = map (attach_probability (p/#n here)) (n here)
                                where
                                attach_probability p' there = (there, p')

merge_cases :: state -> state
  merge_cases = foldr insert []

insert :: (node, probability) -> state -> state
  insert (here, p) [] = [(here, p)]
  insert (here, p) ((there, q):rest)
    = (here, p+q):rest, here=there
    = (here, p):(there, q):rest, here<there
    = (there, q):insert (here, p) rest, here>there


















showstate :: state -> [char]
  showstate s = "NODE\tPROBABILITY\n----\t-----------\n"
                ++ concat (map showstatecase s)
                ++ "\n\n\n"

showstatecase :: (node, probability) -> [char]
  showstatecase (here, p) = shownum here ++ "\t" ++ shownum (100*p) ++ "%\n"

showtrace :: trace -> [char]
  showtrace = ("INITIAL STATE:\n--------------\n\n"++)
              . concat . map ((++"\n\nNEXT STATE:\n-----------\n\n")
                            . showstate)




shownavigate :: net -> node -> [char]
  shownavigate n start = showtrace (navigate n start)

showfinalstate :: net -> node -> [char]
  showfinalstate n start = showstate (final_state n start)





short_descriptions == node -> short_description
short_description == [char]





show_annotated_navigate :: (net, short_descriptions) -> node -> [char]
  show_annotated_navigate (n, sd) start
    = show_annotated_trace sd (navigate n start)

show_annotated_final_state :: (net, short_descriptions) -> node -> [char]
  show_annotated_final_state (n, sd) start
    = show_annotated_state sd (final_state n start)






show_annotated_state :: short_descriptions -> state -> [char]
  show_annotated_state sd s
     = "NODE\tSHORT DESCRIPTION OF CIRCUMSTANCES\tPROBABILITY\n" ++
       "----\t----------------------------------\t-----------\n"
                ++ concat (map (show_annotated_statecase sd) s)
                ++ "\n\n\n"

show_annotated_statecase :: short_descriptions -> (node, probability) -> [char]
  show_annotated_statecase sd (here, p)
     = shownum here ++ "\t"
        ++ first_with_padding ' ' 34 (sd here) ++ "\t"
        ++ shownum (100*p) ++ "%\n"

show_annotated_trace :: short_descriptions -> trace -> [char]
  show_annotated_trace sd
    = ("INITIAL STATE:\n--------------\n\n"++)
       . concat . map ((++"\n\nNEXT STATE:\n-----------\n\n")
                        . show_annotated_state sd)






first_with_padding :: * -> num -> [*] -> [*]
|| like "take", but pads list out if necessary so the given length
|| is always exactly satisfied.
  first_with_padding pad desired_length l
    = error "lists can only be padded to natural-number length!",
        ~integer desired_length \/ desired_length<0
    = rep desired_length pad, l=[]
    = [], desired_length=0
    = (hd l):first_with_padding pad (desired_length-1) (tl l), otherwise
