/**
 * This module contains strategies for checking local structural properties
 * on terms.
 *
 * @author Eelco Visser <visser@acm.org>
 * @author Karl Trygve Kalleberg <karltk@strategoxt.org> - documentation
 *
 */
module term/properties
imports 
  strategy/traversal/simple

strategies

  /**
   * Succeeds if the first argument is a subterm of the second.
   *
   * A term x is a subterm of a term y if x = y
   * or if x is a subterm of one of the chuldren of y.
   *
   * @type  (a, b) -> (a, b)
   */
  is-subterm =
    ?(x, y); where(<oncetd(?x)> y)

  /**
   * Succeeds if the first argument (x) is a subterm of the second (y) and x is not y.
   *
   * @type  (a, b) -> (a, b)
   */
  is-proper-subterm =
    ?(x, y); not(eq); is-subterm

strategies

  /**
   * Succeeds if the first argument (x) is a superterm of the second (y).
   *
   * @type  (a, b) -> (a, b)
   */
  is-superterm =
    ?(x, y); where(<oncetd(?y)> x)

  /**
   * Succeeds if the first argument (x) is a superterm of the second (y) and x is not y.
   *
   * @type  (a, b) -> (a, b)
   */
  is-proper-superterm =
    ?(x, y); not(eq); is-superterm

strategies

  is-proper-subterm-set =
    ?([y|_], xs); where(<fetch(not(?y); oncetd(?y))> xs)

  is-proper-superterm-set =
    ?([x|_], ys); where(<fetch(<is-proper-superterm>(x,<id>))> ys)

strategies


  /**
   * Succeeds if the current term has no direct subterms.
   *
   * @type  a -> a
   */
  is-leaf = 
    all(fail)

  /**
   * Succeeds if the current term has at least one direct subterm.
   *
   * @type  a -> a
   */
  is-inner-node =
    one(id)