[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Exchanging trees



Guido Bosch writes:
 > How can I exchange two arbitrary subtrees of the same tree, i.e.
 > 
 > 	exchange-tree : TREE1, TREE2 -> WHATEVER
 > 
 > regardless of their relative position within the surrounding tree.
 > 
 > Annotations of both of the trees also have to be swapped around:
 > 
 > 
 > 	    /\ 		                    /\
 >         /  \    exchange-tree(T1, T2)   /  \
 > 	  /    \   -------------------->  /    \
 > 	 /x____y\	                 /x____y\
 > 	  |    |  	                  |    |
 >     a1-T1   T2-a2	               a2-T2   T1-a1
 > 

  Well, as there was no answer to my problem, I post my "dirty"
solution that I would like to discuss in order to improve it. 
(The fact that the second tree argument is the atom value of an
atomic tree doesn't change the original problem a lot)

(de :exchange-tree (inline-tree heap-tree)
  ;; Exchange the two trees INLINE-TREE  and HEAP-TREE.
  ;; INLINE-TREE can be any tree, HEAP-TREE must be a tree which
  ;; father is an atomic tree of atom class {tree}

  (let ((inline-tree-father ({tree}:up inline-tree 1))
	(heap-tree-father   ({tree}:up heap-tree 1)))

    (or (and ({operator}:atomic ({tree}:operator heap-tree-father))
	     (eq ({tree}:atom_class heap-tree-father) {tree}))
	(error ':exchange-tree "must be an atomic tree"
	       ({tree}:name heap-tree)))

    ;; capture vtp exceptions and transform them into normal errors
    (vtp-condition-case error

	;; This is quite a big hack. I would prefer to do it better,
	;; but I don't know how ...
	(progn 
	  ;; delete the `father' link, otherwise a `en-contexte' exception
	  ;; is raised for the {tree}:replace operation.
	  ({tree}:father heap-tree ())

	  ;; this may raise an `abstract_syntax' exception. In this
	  ;; case the trees' father has to be restored
	  ({tree}:replace inline-tree heap-tree)
	  ({tree}:atom_replace heap-tree-father inline-tree)

	  ;; For some obscure reasons the father links do not follow.
	  ;; -->  handcraft them!
	  ({tree}:father inline-tree heap-tree-father)
	  ({tree}:father heap-tree inline-tree-father)
	  )

      ((abstract_syntax en_contexte)
       ;; restore the father of the heap tree in case of exception
       ({tree}:father heap-tree heap-tree-father)
       (error ':exchange-tree "VTP exception" (car error-msgs)))

      ;; other exceptions are captured here
      (t (error ':exchange-tree "Exception raised" (car error-msgs))))))



Another related question is the following: 

How can I test whether the abstract syntax constraints are fulfilled
BEFORE using `{tree}:replace'?

	Guido