简体   繁体   中英

Extending a tree in OCaml?

I want to represent game trees in OCaml. The current position is the root, the root's children represent some of the resulting positions after one move, and so forth. I want to expand this game tree dynamically (adding new possible moves one by one).

I have a "position" type. The naive way would be I think:

type tree = Nil | Node of position * (tree list);;

But this does not allow me to increase my tree by adding new moves becauses lists are not mutable. I've also considered:

type tree = Nil | Node of position * ((tree list) ref);;

But I would have to replace the whole list of subtrees every time I want to expand a node, resulting in a lot of useless space I suppose? So the only way I can think of is as follows: type 'a mlist = Empty | Cons of 'a * (('a mlist) ref);; type tree = Nil | Node of position * ((tree mlist) ref);; type 'a mlist = Empty | Cons of 'a * (('a mlist) ref);; type tree = Nil | Node of position * ((tree mlist) ref);;

But it seems extremely inelegant, especially since I could essentially never use either Empty or Nil depending on how I'm coding leaves.

List type in OCaml is immutable, so you can't really do it this way: It is not trivial to add to its tail.

The possibilities you have are:

  • Build the tree from the bottom via recursion - calculate the values and first build leafs of the tree, then continue up to the root. That means you will have to know how deep do you want to go, which may not be an option here, but this solution is pure functional, or
  • Use some mutable representation, eg arrays. That is not pure functional, but is an option, if you need to achieve the mutability.

If you want to keep using pure functional : Make a binary tree type type 'a tree = Nil | F of 'a | Node of 'a tree * position * 'a tree;; type 'a tree = Nil | F of 'a | Node of 'a tree * position * 'a tree;;

The type is still static by itself, but if you create your functions so that they return a new tree, you just have to have an update function who will keep your tree up to date. You will have easier time to add and find elements. Advantage here is that by using binary tree, you'll be faster in finding the elements.

Else, you will have to use hash tables http://caml.inria.fr/pub/docs/manual-ocaml/libref/Hashtbl.html . They are some kind of dynamic array. You have a base size and a growth argument. As long as you keep in size of the current array nothing happen but when you add more elements than the current size is supporting, the hastable evolve and grew bigger depending on the growth argument. You'll have to find the correct arguments so you table don't too much useless space but don't grow to often. :)

Hope it was help full

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM