content: package at.ac.tuwien.kr.alpha.commons;
  
  import at.ac.tuwien.kr.alpha.api.programs.Predicate;
  import at.ac.tuwien.kr.alpha.commons.util.Interner;
  
  /**
   * A predicate as used by the Alpha solver internally.
   * 
   * Copyright (c) 2016-2020, the Alpha Team.
   */
  class PredicateImpl implements Predicate {
  	
  	private static final Interner<PredicateImpl> INTERNER = new Interner<>();
  
  	private final String name;
  	private final int arity;
  	private final boolean internal;
  	private final boolean solverInternal;
  
  	PredicateImpl(String name, int arity, boolean internal, boolean solverInternal) {
  		this.name = name;
  		this.arity = arity;
  		this.internal = internal;
  		this.solverInternal = solverInternal;
  	}
  
  	static PredicateImpl getInstance(String symbol, int arity, boolean internal, boolean solverInternal) {
  		return INTERNER.intern(new PredicateImpl(symbol, arity, internal, solverInternal));
  	}
  
  	@Override
  	public int hashCode() {
  		int result = name != null ? name.hashCode() : 0;
  		result = 31 * result + arity;
  		result = 31 * result + (internal ? 1 : 0);
  		return result;
  	}
  
  	@Override
  	public boolean equals(Object o) {
  		if (this == o) {
  			return true;
  		}
  
  		if (!(o instanceof PredicateImpl)) {
  			return false;
  		}
  
  		PredicateImpl predicate = (PredicateImpl) o;
  
  		if (arity != predicate.arity) {
  			return false;
  		}
  
  		if (internal != predicate.internal) {
  			return false;
  		}
  
  		return name != null ? name.equals(predicate.name) : predicate.name == null;
  	}
  
  	/**
  	 * Marks internal predicates that should not be shown/printed in answer sets.
  	 * @return true iff this Predicate should be omitted from answer sets.
  	 */
  	@Override
  	public boolean isInternal() {
  		return internal;
  	}
  
  	/**
  	 * Marks predicates that are used purely for encoding rules by NoGoods in the solver component. Solver internal
  	 * predicates are guaranteed to not occur in any rule bodies and hence are ignored by the grounder.
  	 * @return true iff this Predicate is internal to the solver component.
  	 */
  	@Override
  	public boolean isSolverInternal() {
  		return solverInternal;
  	}
  
  	@Override
  	public String getName() {
  		return name;
  	}
  
  	@Override
  	public int getArity() {
  		return arity;
  	}
  
  	@Override
  	public String toString() {
  		return name + "/" + arity;
  	}
  }
  