Package aterm.pure

Source Code of aterm.pure.ATermApplImpl

/*
* Copyright (c) 2002-2007, CWI and INRIA
*
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*     * Redistributions of source code must retain the above copyright
*       notice, this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of the University of California, Berkeley nor the
*       names of its contributors may be used to endorse or promote products
*       derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package aterm.pure;

import java.util.List;

import jjtraveler.VisitFailure;

import shared.SharedObject;
import aterm.AFun;
import aterm.ATerm;
import aterm.ATermAppl;
import aterm.ATermList;
import aterm.ATermPlaceholder;
import aterm.Visitable;
import aterm.Visitor;

public class ATermApplImpl extends ATermImpl implements ATermAppl {
  private AFun fun;

  private ATerm[] args;

  /**
   * @depricated Use the new constructor instead.
   * @param factory
   */
  protected ATermApplImpl(PureFactory factory) {
    super(factory);
  }
 
  protected ATermApplImpl(PureFactory factory, ATermList annos, AFun fun, ATerm[] i_args) {
    super(factory, annos);
   
    this.fun = fun;
    this.args = i_args;
   
    setHashCode(hashFunction());
  }

  public int getType() {
    return ATerm.APPL;
  }

  /**
   * @depricated Use the new constructor instead.
   * @param hashCode
   * @param annos
   * @param fun
   * @param i_args
   */
  protected void init(int hashCode, ATermList annos, AFun fun, ATerm[] i_args) {
    super.init(hashCode, annos);
    this.fun = fun;
    this.args = new ATerm[i_args.length];

    System.arraycopy(i_args, 0, args, 0, args.length);
  }

  /**
   * @depricated Use the new constructor instead.
   * @param annos
   * @param fun
   * @param i_args
   */
  protected void initHashCode(ATermList annos, AFun fun, ATerm[] i_args) {
    this.fun = fun;
    this.args = i_args;
    this.internSetAnnotations(annos);
    this.setHashCode(this.hashFunction());
  }

  public SharedObject duplicate() {
    return this;
  }

  protected ATermAppl make(AFun fun, ATerm[] i_args, ATermList annos) {
    return getPureFactory().makeAppl(fun, i_args, annos);
  }

  protected ATermAppl make(AFun fun, ATerm[] i_args) {
    return make(fun, i_args, getPureFactory().makeList());
  }

  public boolean equivalent(SharedObject obj){
    if(obj instanceof ATermAppl){
      ATermAppl peer = (ATermAppl) obj;
      if(peer.getType() != getType()) return false;
     
      if(peer.getAFun().equals(fun)){
        for(int i = 0; i < args.length; i++){
          if(!peer.getArgument(i).equals(args[i])){
            return false;
          }
        }
        return peer.getAnnotations().equals(getAnnotations());
      }
    }
    return false;
  }

  protected boolean match(ATerm pattern, List<Object> list) {
    if (pattern.getType() == APPL) {
      ATermAppl appl = (ATermAppl) pattern;
      if (fun.equals(appl.getAFun())) {
        return matchArguments(appl.getArgumentArray(), list);
      }
      return false;
    }

    if (pattern.getType() == PLACEHOLDER) {
      ATerm type = ((ATermPlaceholder) pattern).getPlaceholder();
      if (type.getType() == APPL) {
        ATermAppl appl = (ATermAppl) type;
        AFun afun = appl.getAFun();
        if (afun.getName().equals("appl") && !afun.isQuoted()) {
          list.add(fun.getName());
          return matchArguments(appl.getArgumentArray(), list);
        } else if (afun.getName().equals("str") && !afun.isQuoted()) {
          if (fun.isQuoted()) {
            list.add(fun.getName());
            return matchArguments(appl.getArgumentArray(), list);
          }
        } else if (afun.getName().equals("fun") && !afun.isQuoted()) {
          if (!fun.isQuoted()) {
            list.add(fun.getName());
            return matchArguments(appl.getArgumentArray(), list);
          }
        } else if (afun.getName().equals("id") && !afun.isQuoted()) {
          if (!fun.isQuoted()) {
            list.add(fun.getName());
            return matchArguments(appl.getArgumentArray(), list);
          }
        }
      }
    }

    return super.match(pattern, list);
  }

  boolean matchArguments(ATerm[] pattern_args, List<Object> list) {
    for (int i = 0; i < args.length; i++) {
      if (i >= pattern_args.length) {
        return false;
      }

      ATerm arg = args[i];
      ATerm pattern_arg = pattern_args[i];

      if (pattern_arg.getType() == PLACEHOLDER) {
        ATerm ph_type = ((ATermPlaceholder) pattern_arg)
          .getPlaceholder();
        if (ph_type.getType() == APPL) {
          ATermAppl appl = (ATermAppl) ph_type;
          if (appl.getName().equals("list") && appl.getArguments().isEmpty()) {
            ATermList result = getPureFactory().getEmpty();
            for (int j = args.length - 1; j >= i; j--) {
              result = result.insert(args[j]);
            }
            list.add(result);
            return true;
          }
        }
      }

      List<Object> submatches = arg.match(pattern_arg);
      if (submatches == null) {
        return false;
      }
      list.addAll(submatches);
    }

    return args.length == pattern_args.length;
  }

  public ATerm[] getArgumentArray() {
    return args;
  }

  public AFun getAFun() {
    return fun;
  }

  public ATermList getArguments() {
    ATermList result = getPureFactory().getEmpty();

    for (int i = args.length - 1; i >= 0; i--) {
      result = result.insert(args[i]);
    }

    return result;
  }

  public ATerm getArgument(int index) {
    return args[index];
  }

  public ATermAppl setArgument(ATerm newarg, int index) {
    ATerm[] newargs = (ATerm[]) args.clone();
    newargs[index] = newarg;

    return make(fun, newargs, getAnnotations());
  }

  public boolean isQuoted() {
    return fun.isQuoted();
  }

  public String getName() {
    return fun.getName();
  }

  public int getArity() {
    return args.length;
  }

  public ATerm make(List<Object> arguments) {
    ATerm[] newargs = new ATerm[this.args.length];
    for(int i = 0; i < args.length; i++){
      newargs[i] = args[i].make(arguments);
    }
   
    PureFactory pf = getPureFactory();
    ATermList empty = pf.getEmpty();
   
    ATermList annos = getAnnotations();
    ATermList tempAnnos = empty;
    while(annos != empty){
      tempAnnos = pf.makeList(annos.getFirst().make(arguments), tempAnnos);
      annos = annos.getNext();
    }
    ATermList newAnnos = tempAnnos.reverse();
   
    return getPureFactory().makeAppl(fun, newargs, newAnnos);
  }

  public ATerm setAnnotations(ATermList annos) {
  return getPureFactory().makeAppl(fun, args, annos);
  }

  public Visitable accept(Visitor v) throws VisitFailure {
    return v.visitAppl(this);
  }

  public int getNrSubTerms() {
    return args.length;
  }

  public ATerm getSubTerm(int index) {
    return args[index];
  }

  public ATerm setSubTerm(int index, ATerm t) {
    return setArgument(t, index);
  }

  private Object[] serialize() {
    int arity = getArity();
    Object[] o = new Object[arity + 2];
    for (int i = 0; i < arity; i++) {
      o[i] = getArgument(i);
    }
    o[arity] = getAnnotations();
    o[arity + 1] = getAFun();
    return o;
  }

  protected int hashFunction() {
    int initval = 0; /* the previous hash value */
    int a, b, c, len;

    /* Set up the internal state */
    len = getArity();
    a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
    c = initval; /* the previous hash value */
    /*---------------------------------------- handle most of the key */
    if (len >= 12) {
      return staticDoobs_hashFuntion(serialize());
      // return PureFactory.doobs_hashFunction(serialize());
    }

    /*------------------------------------- handle the last 11 bytes */
    c += len;
    c += (getAnnotations().hashCode() << 8);
    b += (getAFun().hashCode() << 8);

    switch (len) {
      case 11:
        c += (getArgument(10).hashCode() << 24);
      case 10:
        c += (getArgument(9).hashCode() << 16);
      case 9:
        c += (getArgument(8).hashCode() << 8);
      case 8:
        b += (getArgument(7).hashCode() << 24);
      case 7:
        b += (getArgument(6).hashCode() << 16);
      case 6:
        b += (getArgument(5).hashCode() << 8);
      case 5:
        b += (getArgument(4).hashCode());
      case 4:
        a += (getArgument(3).hashCode() << 24);
      case 3:
        a += (getArgument(2).hashCode() << 16);
      case 2:
        a += (getArgument(1).hashCode() << 8);
      case 1:
        a += (getArgument(0).hashCode());
        /* case 0: nothing left to add */
    }
    a -= b;
    a -= c;
    a ^= (c >> 13);
    b -= c;
    b -= a;
    b ^= (a << 8);
    c -= a;
    c -= b;
    c ^= (b >> 13);
    a -= b;
    a -= c;
    a ^= (c >> 12);
    b -= c;
    b -= a;
    b ^= (a << 16);
    c -= a;
    c -= b;
    c ^= (b >> 5);
    a -= b;
    a -= c;
    a ^= (c >> 3);
    b -= c;
    b -= a;
    b ^= (a << 10);
    c -= a;
    c -= b;
    c ^= (b >> 15);

    /*-------------------------------------------- report the result */
    return c;
  }

  static private int staticDoobs_hashFuntion(Object[] o) {
    // System.out.println("static doobs_hashFuntion");

    int initval = 0; /* the previous hash value */
    int a, b, c, len;

    /* Set up the internal state */
    len = o.length;
    a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */
    c = initval; /* the previous hash value */

    /*---------------------------------------- handle most of the key */
    int k = 0;
    while (len >= 12) {
      a += (o[k + 0].hashCode() + (o[k + 1].hashCode() << 8)
          + (o[k + 2].hashCode() << 16) + (o[k + 3].hashCode() << 24));
      b += (o[k + 4].hashCode() + (o[k + 5].hashCode() << 8)
          + (o[k + 6].hashCode() << 16) + (o[k + 7].hashCode() << 24));
      c += (o[k + 8].hashCode() + (o[k + 9].hashCode() << 8)
          + (o[k + 10].hashCode() << 16) + (o[k + 11].hashCode() << 24));
      // mix(a,b,c);
      a -= b;
      a -= c;
      a ^= (c >> 13);
      b -= c;
      b -= a;
      b ^= (a << 8);
      c -= a;
      c -= b;
      c ^= (b >> 13);
      a -= b;
      a -= c;
      a ^= (c >> 12);
      b -= c;
      b -= a;
      b ^= (a << 16);
      c -= a;
      c -= b;
      c ^= (b >> 5);
      a -= b;
      a -= c;
      a ^= (c >> 3);
      b -= c;
      b -= a;
      b ^= (a << 10);
      c -= a;
      c -= b;
      c ^= (b >> 15);

      k += 12;
      len -= 12;
    }

    /*------------------------------------- handle the last 11 bytes */
    c += o.length;
    switch (len) /* all the case statements fall through */
    {
      case 11:
        c += (o[k + 10].hashCode() << 24);
      case 10:
        c += (o[k + 9].hashCode() << 16);
      case 9:
        c += (o[k + 8].hashCode() << 8);
        /* the first byte of c is reserved for the length */
      case 8:
        b += (o[k + 7].hashCode() << 24);
      case 7:
        b += (o[k + 6].hashCode() << 16);
      case 6:
        b += (o[k + 5].hashCode() << 8);
      case 5:
        b += o[k + 4].hashCode();
      case 4:
        a += (o[k + 3].hashCode() << 24);
      case 3:
        a += (o[k + 2].hashCode() << 16);
      case 2:
        a += (o[k + 1].hashCode() << 8);
      case 1:
        a += o[k + 0].hashCode();
        /* case 0: nothing left to add */
    }
    // mix(a,b,c);
    a -= b;
    a -= c;
    a ^= (c >> 13);
    b -= c;
    b -= a;
    b ^= (a << 8);
    c -= a;
    c -= b;
    c ^= (b >> 13);
    a -= b;
    a -= c;
    a ^= (c >> 12);
    b -= c;
    b -= a;
    b ^= (a << 16);
    c -= a;
    c -= b;
    c ^= (b >> 5);
    a -= b;
    a -= c;
    a ^= (c >> 3);
    b -= c;
    b -= a;
    b ^= (a << 10);
    c -= a;
    c -= b;
    c ^= (b >> 15);

    /*-------------------------------------------- report the result */
    return c;
  }

}
TOP

Related Classes of aterm.pure.ATermApplImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.