2

I have a question about abstract syntax trees.
In particular I want to sort several trees with an particular term order.

How can one define a term order for an AST with the following properties:

  1. For allmost all terms, the order behaves exactly like the standard built-in order of terms.
  2. Deeply nested in the AST there are terms of functor pos/6 which denote source-positions. These functors should be ignored in the term order, i.e. all terms of functor pos should compare as equal.

Is is possible to extend the built-in term-order with a special case for 'pos' ?

What is the most efficient solution, what is the most readable solution ?

Maybe I should also mention that our ASTs can be quite big, I just benchmarked one AST, which has 217479 proper functors (ignoring the nullary atoms)

Sam DeHaan
  • 10,246
  • 2
  • 40
  • 48
  • Maybe I should also mention that our ASTs can be quite big, I just benchmarked one AST, which has 217479 proper functors (ignoring the nullary atoms) – user1310130 Apr 03 '12 at 11:24

2 Answers2

4

I would define a relation ast_without_pos/2 that relates an AST A0 to a term A that is the same as A0 except that all pos/6 subterms are replaced by the same term, say the atom t, and then use the standard term order on these resulting terms. I think this is very readable, and also reasonably efficient.

mat
  • 40,498
  • 3
  • 51
  • 78
  • This means that one effectively copys the complete AST, though, it is most likely that one only has to look at a few nodes to actually determine the relation between two ASTs. – user1310130 Apr 03 '12 at 11:34
  • 1
    You can easily write it in such a way that whatever _can_ be shared between the terms _is_ shared in memory. For example: ast_without_pos(X, Y) :- X = something_different_from_pos, !, Y = X. etc. – mat Apr 03 '12 at 11:44
  • Actually every node in the AST carries information about the source-location, so there is a pos-sub-term in every node and there are not many opportunities for sharing. Is there a way to do it that ressembles Haskell laziness, i.e only computes the terms that are needed? – user1310130 Apr 03 '12 at 11:56
  • 1
    Even without laziness: The resulting term will already be significantly smaller if all pos/6 subterms are replaced by a single atom. I find it improbable that you are exactly at such a memory boundary that you can represent the original terms, but not 2 significantly smaller additional "copies". – mat Apr 03 '12 at 12:16
  • Ok, it would be possible concerning the memory overhead, but it still seems be slow to make a complete copy, just to look at a small fraction of the nodes. – user1310130 Apr 03 '12 at 12:25
  • The same for speed: Comparison already is a linear operation, so is copying. – mat Apr 03 '12 at 12:50
  • Yes, the worst case complexity is linear. (That is the case that both ASTs are indeet identical). I want to sort a list of ASTs of which I know that they are all different and its also very likely that they differ on a position close to the root node. – user1310130 Apr 03 '12 at 13:00
  • Well then you can easily write a comparison predicate and use for example predsort/3. In my opinion, instead of discussing this further, you should actually try it out, the simplest approach (which I think I outlined above) first, and if that is too slow, try other ways. – mat Apr 03 '12 at 13:49
2

You could look at Zippers over the AST?

Here is an example over lists:

http://blog.logtalk.org/2013/04/zipper-lists-in-prolog/

If you get the sources for Termite, I think you will find a more general implementation over trees.

http://www.complang.tuwien.ac.at/adrian/termite/Manual/Contents.html

Any help to you?

user2800708
  • 1,890
  • 2
  • 18
  • 31