All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.ibm.wala.fixedpoint.impl.GeneralStatement Maven / Gradle / Ivy

The newest version!
/*
 * Copyright (c) 2002 - 2006 IBM Corporation.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 */
package com.ibm.wala.fixedpoint.impl;

import com.ibm.wala.fixpoint.AbstractOperator;
import com.ibm.wala.fixpoint.AbstractStatement;
import com.ibm.wala.fixpoint.FixedPointConstants;
import com.ibm.wala.fixpoint.IVariable;
import org.jspecify.annotations.NullUnmarked;

/** Represents a single step in an iterative solver */
public abstract class GeneralStatement>
    extends AbstractStatement> {

  protected final T lhs;

  protected final T[] rhs;

  private final int hashCode;

  private final AbstractOperator operator;

  /**
   * Evaluate this equation, setting a new value for the left-hand side.
   *
   * @return a constant defined by {@link FixedPointConstants} that reflects whether the lhs value
   *     changed
   */
  @Override
  public byte evaluate() {
    return operator.evaluate(lhs, rhs);
  }

  /**
   * Return the left-hand side of this equation.
   *
   * @return the lattice cell this equation computes
   */
  @Override
  public T getLHS() {
    return lhs;
  }

  /**
   * Does this equation contain an appearance of a given cell?
   *
   * 

Note: this uses reference equality, assuming that the variables are canonical! This is * fragile. TODO: Address it perhaps, but be careful not to sacrifice efficiency. * * @param cell the cell in question * @return true or false */ @Override public boolean hasVariable(T cell) { if (lhs == cell) { return true; } for (T rh : rhs) { if (rh == cell) return true; } return false; } /** * Constructor for case of zero operands on the right-hand side. * * @param lhs the lattice cell set by this equation * @param operator the equation operator */ @NullUnmarked public GeneralStatement(T lhs, AbstractOperator operator) { super(); if (operator == null) { throw new IllegalArgumentException("null operator"); } this.operator = operator; this.lhs = lhs; this.rhs = null; this.hashCode = makeHashCode(); } /** * Constructor for case of two operands on the right-hand side. * * @param lhs the lattice cell set by this equation * @param operator the equation operator * @param op1 the first operand on the rhs * @param op2 the second operand on the rhs */ public GeneralStatement(T lhs, AbstractOperator operator, T op1, T op2) { super(); if (operator == null) { throw new IllegalArgumentException("null operator"); } this.operator = operator; this.lhs = lhs; rhs = makeRHS(2); rhs[0] = op1; rhs[1] = op2; this.hashCode = makeHashCode(); } /** * Constructor for case of three operands on the right-hand side. * * @param lhs the lattice cell set by this equation * @param operator the equation operator * @param op1 the first operand on the rhs * @param op2 the second operand on the rhs * @param op3 the third operand on the rhs */ public GeneralStatement(T lhs, AbstractOperator operator, T op1, T op2, T op3) { super(); if (operator == null) { throw new IllegalArgumentException("null operator"); } this.operator = operator; rhs = makeRHS(3); this.lhs = lhs; rhs[0] = op1; rhs[1] = op2; rhs[2] = op3; this.hashCode = makeHashCode(); } /** * Constructor for case of more than three operands on the right-hand side. * * @param lhs the lattice cell set by this equation * @param operator the equation operator * @param rhs the operands of the right-hand side in order * @throws IllegalArgumentException if rhs is null */ public GeneralStatement(T lhs, AbstractOperator operator, T[] rhs) { super(); if (operator == null) { throw new IllegalArgumentException("null operator"); } if (rhs == null) { throw new IllegalArgumentException("rhs is null"); } this.operator = operator; this.lhs = lhs; this.rhs = rhs.clone(); this.hashCode = makeHashCode(); } /** TODO: use a better hash code? */ private static final int[] primes = {331, 337, 347, 1277}; private int makeHashCode() { int result = operator.hashCode(); if (lhs != null) result += lhs.hashCode() * primes[0]; for (int i = 0; i < Math.min(rhs.length, 2); i++) { if (rhs[i] != null) { result += primes[i + 1] * rhs[i].hashCode(); } } return result; } protected abstract T[] makeRHS(int size); @Override public int hashCode() { return hashCode; } @Override public boolean equals(Object o) { if (o == null) { return false; } if (getClass().equals(o.getClass())) { GeneralStatement other = (GeneralStatement) o; if (hashCode == other.hashCode) { if (lhs == null || other.lhs == null) { if (other.lhs != lhs) { return false; } } else if (!lhs.equals(other.lhs)) { return false; } if (operator.equals(other.operator) && rhs.length == other.rhs.length) { for (int i = 0; i < rhs.length; i++) { if (rhs[i] == null || other.rhs[i] == null) { if (other.rhs[i] != rhs[i]) { return false; } } else if (!rhs[i].equals(other.rhs[i])) { return false; } } return true; } } } return false; } @Override public AbstractOperator getOperator() { return operator; } @Override public T[] getRHS() { return rhs; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy