/** * */ package xhail.core.entities; import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.apache.commons.collections4.iterators.ArrayIterator; import xhail.core.Buildable; import xhail.core.Config; import xhail.core.Dialler; /** * @author stefano * */ public class Answers implements Iterable<Answer> { public static class Builder implements Buildable<Answers> { private Set<Answer> answers = new HashSet<>(); private Config config; private int count = 0; private Values values = null; public Builder(Config config) { if (null == config) throw new IllegalArgumentException("Illegal 'config' argument in Answers.Builder.Builder(Config): " + config); this.config = config; } @Override public Answers build() { return new Answers(this); } public Builder clear() { first = -1L; this.answers.clear(); this.count = 0; this.values = null; return this; } public final boolean isMeaningful() { for (Answer answer : answers) if (answer.isMeaningful()) return true; return false; } public Builder put(Values values, Answer answer) { if (null == values) throw new IllegalArgumentException("Illegal 'values' argument in Answers.Builder.putAnswer(Values, Answer): " + values); if (null == answer) throw new IllegalArgumentException("Illegal 'answer' argument in Answers.Builder.putAnswer(Values, Answer): " + answer); if (first < 0L) first = System.nanoTime(); int order = null == this.values ? -1 : values.compareTo(this.values); if (order < 0) { this.answers.clear(); this.values = values; } if (order <= 0) this.answers.add(answer); count += 1; return this; } public Builder remove(Values values, Answer answer) { if (null == values) throw new IllegalArgumentException("Illegal 'values' argument in Answers.Builder.removeAnswer(Values, Answer): " + values); if (null == answer) throw new IllegalArgumentException("Illegal 'answer' argument in Answers.Builder.removeAnswer(Values, Answer): " + answer); if (null != this.values && 0 == values.compareTo(this.values)) if (this.answers.remove(answer)) count -= 1; return this; } public final int size() { return answers.size(); } } private static long abduction = 0L; private static long deduction = 0L; private static long first = -1L; private static long induction = 0L; private static long loading = -1L; private static final double NORMALIZER = 1_000_000_000.0; private static long start = -1L; public static final double getAbduction() { return abduction / NORMALIZER; } public static final double getDeduction() { return deduction / NORMALIZER; } public static final double getFirst() { if (first < 0L || start < 0L) return 0L; return (first - start) / NORMALIZER; } public static final double getInduction() { return induction / NORMALIZER; } public static final double getLoading() { if (loading < 0L || start < 0L) return 0L; return (loading - start) / NORMALIZER; } public static final double getNow() { if (start < 0L) return 0L; return (System.nanoTime() - start) / NORMALIZER; } public static final void loaded() { if (loading < 0L) loading = System.nanoTime(); } public static final void started() { if (start < 0L) start = System.nanoTime(); } public static Map.Entry<Values, Collection<Collection<String>>> timeAbduction(int iter, Dialler dialer) { if (iter < 0) throw new IllegalArgumentException("Illegal 'iter' argument in Answers.timeAbduction(int, Dialer): " + iter); if (null == dialer) throw new IllegalArgumentException("Illegal 'dialer' argument in Answers.timeAbduction(int, Dialer): " + dialer); long time = System.nanoTime(); Map.Entry<Values, Collection<Collection<String>>> result = dialer.execute(iter); abduction += (System.nanoTime() - time); return result; } public static Hypothesis timeDeduction(Grounding grounding, Collection<String> output) { if (null == grounding) throw new IllegalArgumentException("Illegal 'grounding' argument in Answers.timeDeduction(Grounding, Collection<String>): " + grounding); if (null == output) throw new IllegalArgumentException("Illegal 'output' argument in Answers.timeDeduction(Grounding, Collection<String>): " + output); long time = System.nanoTime(); Hypothesis result = new Hypothesis.Builder(grounding).parse(output).build(); result.getHypotheses(); deduction += (System.nanoTime() - time); return result; } public static Grounding timeDeduction(Problem problem, Collection<String> output) { if (null == problem) throw new IllegalArgumentException("Illegal 'problem' argument in Answers.timeDeduction(Problem, Collection<String>): " + problem); if (null == output) throw new IllegalArgumentException("Illegal 'output' argument in Answers.timeDeduction(Problem, Collection<String>): " + output); long time = System.nanoTime(); Grounding result = new Grounding.Builder(problem).parse(output).build(); result.getGeneralisation(); deduction += (System.nanoTime() - time); return result; } public static Map.Entry<Values, Collection<Collection<String>>> timeInduction(int iter, Dialler dialer) { if (iter < 0) throw new IllegalArgumentException("Illegal 'iter' argument in Answers.timeInduction(int, Dialer): " + iter); if (null == dialer) throw new IllegalArgumentException("Illegal 'dialer' argument in Answers.timeInduction(Dialer): " + dialer); long time = System.nanoTime(); Map.Entry<Values, Collection<Collection<String>>> result = dialer.execute(iter); induction += (System.nanoTime() - time); return result; } private final Answer[] answers; private final Config config; private final int count; private final Values values; private Answers(Builder builder) { if (null == builder) throw new IllegalArgumentException("Illegal 'builder' argument in Answers(Answers.Builder): " + builder); this.answers = builder.answers.toArray(new Answer[builder.answers.size()]); this.config = builder.config; this.count = builder.count; this.values = builder.values; } public final int count() { return count; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Answers other = (Answers) obj; if (!Arrays.equals(answers, other.answers)) return false; if (values == null) { if (other.values != null) return false; } else if (!values.equals(other.values)) return false; return true; } public final Answer getAnswer(int index) { if (index < 0 || index >= answers.length) throw new IndexOutOfBoundsException("Illegal 'index' argument in Answers.getAnswer(int): " + index); return answers[index]; } public final Answer[] getAnswers() { return answers; } public final Config getConfig() { return config; } public final Values getValues() { return values; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + Arrays.hashCode(answers); result = prime * result + ((values == null) ? 0 : values.hashCode()); return result; } public final boolean isEmpty() { return 0 == answers.length; } @Override public Iterator<Answer> iterator() { return new ArrayIterator<>(answers); } public final int size() { return answers.length; } }