 
 
 
-(defn
+(defn-
   ancestors-of-element
-  "Returns the lazy sequence of non-nil ancestors of the given ProgramElement. "
-  [element]
-  (filter (complement nil?)
-          (iterate (fn [ancestor] (.getParent ancestor)))))
-
-
-
-
-  
-
-
-
-
-;does not work yet
-(defn
-  element-enclosing-aspect
+  "Returns the ancestor chain of the given ProgramElement.
+   First element is the immediate parent."
+  ([element] 
+    (ancestors-of-element (.getParent element) []))
+  ([parent sofar]
+    (if-not
+      (nil? parent)
+      (recur (.getParent parent) (conj sofar parent))
+      sofar)))
+
+(defn-
+  enclosingtypedeclaration-of-element
+  "Returns the most enclosing class, aspect or enum declaration
+   in which the given ProgramElement resides."
+  [element] 
+  (letfn [(typedeclaration? 
+            [element]
+            (let [kind (.getKind element)]
+              (or (= kind (IProgramElement$Kind/CLASS))
+                  (= kind (IProgramElement$Kind/ENUM))
+                  (= kind (IProgramElement$Kind/ASPECT)))))
+          (ancestortypedeclaration 
+            [parent]
+            (if-not
+              (nil? parent)
+              (if 
+                (typedeclaration? parent)
+                parent
+                (recur (.getParent parent)))))]
+         (ancestortypedeclaration (.getParent element))))
+    
+(defn
+  element-enclosingtypedeclaration-element
   "Relation between a ProgramElement and its enclosing aspect (if any)."
-  [?element ?aspect]
-  (fresh [?aspkind]
-         (equals ?aspkind (IProgramElement$Kind/ASPECT))
-         (conde [(element-parent ?element ?aspect)
-                 (!= ?aspect nil)
-                 (element-kind ?aspect ?aspkind)]
-                [(fresh [?intermediate]
-                        (element-parent ?element ?intermediate)
-                        (element-enclosing-aspect ?element ?aspect))])))
-
+  [?element ?typedeclaration]
+  (all
+    (element ?element)
+    (equals ?typedeclaration (enclosingtypedeclaration-of-element ?element))
+    (!= nil ?typedeclaration)))
+
+(defn
+  elementaspect
+  [?element]
+  (all
+    (element ?element)
+    (equals (IProgramElement$Kind/ASPECT) (.getKind ?element))))
+
+(defn
+  elementclass
+  [?element]
+  (all
+    (element ?element)
+    (equals (IProgramElement$Kind/CLASS) (.getKind ?element))))
+
+(defn
+  elementenum
+  [?element]
+  (all
+    (element ?element)
+    (equals (IProgramElement$Kind/ENUM) (.getKind ?element))))
+
+(defn
+  elementtypedeclaration
+  [?element]
+  (conde
+    [(elementenum ?element)]
+    [(elementclass ?element)]
+    [(elementaspect ?element)]))
+
+    
 
 
 

       (equals ?resolvedtype (.getValue ?entry))))
 
;can be used to go from xcut to weaverworld types
(defn
  weaverworld-signature-resolvedtype
  "Non-relational. Unifies ?resolved-type with the type known to the AspectJ weaver




;;todo:
;;take into account kinds of advice
;;implicit precedence, precedence assumption
