/** * */ package xhail.core.terms; import java.util.Map; import java.util.Set; import xhail.core.Buildable; /** * @author stefano * */ public class Placemarker implements SchemeTerm { public static class Builder implements Buildable<Placemarker> { private String identifier; private Type type = Type.CONSTANT; public Builder(String identifier) { if (null == identifier || (identifier = identifier.trim()).isEmpty() || identifier.charAt(0) < 'a' || identifier.charAt(0) > 'z') throw new IllegalArgumentException("Illegal 'identifier' argument in Placemarker.Builder(String): " + identifier); this.identifier = identifier; } @Override public Placemarker build() { return new Placemarker(this); } public Builder setIdentifier(String identifier) { if (null == identifier || (identifier = identifier.trim()).isEmpty() || identifier.charAt(0) < 'a' || identifier.charAt(0) > 'z') throw new IllegalArgumentException("Illegal 'identifier' argument in Placemarker.Builder.setIdentifier(String): " + identifier); this.identifier = identifier; return this; } public Builder setType(Type type) { if (null == type) throw new IllegalArgumentException("Illegal 'type' argument in Placemarker.Builder.setType(Type): " + type); this.type = type; return this; } } public static enum Type { CONSTANT("$", CONSTANT_STRING), INPUT("+", INPUT_STRING), OUTPUT("-", OUTPUT_STRING); private final String internal; private final String symbol; private Type(String symbol, String internal) { this.internal = internal; this.symbol = symbol; } public final String getInternal() { return internal; } @Override public String toString() { return symbol; } } public static final String CONSTANT_STRING = "internal_const_par"; public static final String INPUT_STRING = "internal_input_par"; public static final String OUTPUT_STRING = "internal_output_par"; private final String identifier; private final Type type; private Placemarker(Builder builder) { if (null == builder) throw new IllegalArgumentException("Illegal 'builder' argument in Placemarker(Placemarker.Builder): " + builder); this.identifier = builder.identifier; this.type = builder.type; } public final SchemeTerm decode() { SchemeTerm term = new Scheme.Builder(identifier).build(); return new Scheme.Builder(type.getInternal()).addTerm(term).build(); } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Placemarker other = (Placemarker) obj; if (identifier == null) { if (other.identifier != null) return false; } else if (!identifier.equals(other.identifier)) return false; if (type != other.type) return false; return true; } @Override public Term generalises(Set<Variable> set) { if (null == set) throw new IllegalArgumentException("Illegal 'set' argument in Placemarker.generalises(Set<Variable>): " + set); Variable var = new Variable.Builder("V" + (1 + set.size())).setType(this).build(); set.add(var); return var; } @Override public Term generalises(Term term, Map<Term, Variable> map) { if (null == term) throw new IllegalArgumentException("Illegal 'term' argument in Placemarker.generalises(Term, Map<Term, Variable>): " + term); if (null == map) throw new IllegalArgumentException("Illegal 'map' argument in Placemarker.generalises(Term, Map<Term, Variable>): " + map); if (Type.INPUT == type || Type.OUTPUT == type) { Variable var = map.get(term); if (null == var) { var = new Variable.Builder("V" + (1 + map.size())).setType(this).build(); map.put(term, var); } return var; } else return term; } public final String getIdentifier() { return identifier; } public final Type getType() { return type; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((identifier == null) ? 0 : identifier.hashCode()); result = prime * result + ((type == null) ? 0 : type.hashCode()); return result; } // @Override // public Map<Term, Collection<Atom>> matching(Set<Term> usables, Map<SchemeTerm, Set<Atom>> parts) { // if (Type.INPUT == type) { // Map<Term, Collection<Atom>> result = new HashMap<>(); // for (Term term : usables) // result.put(term, Collections.emptySet()); // return result; // } else if (Type.OUTPUT == type) { // Set<Atom> next = new HashSet<>(); // for (Atom term : parts.get(this)) // next.add((Atom) term.getTerm(0)); // Map<Term, Collection<Atom>> result = new HashMap<>(); // for (Atom term : parts.get(this)) // result.put(term, next); // return result; // } else if (Type.CONSTANT == type) { // Map<Term, Collection<Atom>> result = new HashMap<>(); // for (Term term : parts.get(this)) // result.put(term, Collections.emptySet()); // return result; // } else // return null; // } @Override public String toString() { return "" + type + identifier; } }