/* * TruthValue.java * * Copyright (C) 2008 Pei Wang * * This file is part of Open-NARS. * * Open-NARS is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 2 of the License, or * (at your option) any later version. * * Open-NARS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Open-NARS. If not, see <http://www.gnu.org/licenses/>. */ package nars.entity; import nars.config.Parameters; import static nars.config.Parameters.TRUTH_EPSILON; import nars.io.Symbols; import nars.io.Texts; import nars.language.Term; public class TruthValue implements Cloneable { // implements Cloneable { final static Term Truth_TRUE = new Term("TRUE"); final static Term Truth_FALSE = new Term("FALSE"); final static Term Truth_UNSURE = new Term("UNSURE"); /** * The character that marks the two ends of a truth value */ private static final char DELIMITER = Symbols.TRUTH_VALUE_MARK; /** * The character that separates the factors in a truth value */ private static final char SEPARATOR = Symbols.VALUE_SEPARATOR; /** * The frequency factor of the truth value */ private float frequency; /** * The confidence factor of the truth value */ private float confidence; /** * Whether the truth value is derived from a definition */ private boolean analytic = false; public TruthValue() { this(0,0); } /** * Constructor with two ShortFloats * * @param f The frequency value * @param c The confidence value */ public TruthValue(final float f, final float c) { this(f, c, false); } /** * Constructor with two ShortFloats * * @param f The frequency value * @param c The confidence value * */ public TruthValue(final float f, final float c, final boolean b) { setFrequency(f); setConfidence(c); setAnalytic(b); } /** * Constructor with a TruthValue to clone * * @param v The truth value to be cloned */ public TruthValue(final TruthValue v) { frequency = v.getFrequency(); confidence = v.getConfidence(); analytic = v.getAnalytic(); } /** * Get the frequency value * * @return The frequency value */ public float getFrequency() { //return Math.round(frequency * TRUTH_PRECISION) / TRUTH_PRECISION; return frequency; } /** * Get the confidence value * * @return The confidence value */ public float getConfidence() { //return Math.round(confidence * TRUTH_PRECISION) / TRUTH_PRECISION; return confidence; } public TruthValue setFrequency(final float f) { this.frequency = f; return this; } public TruthValue setConfidence(float c) { this.confidence = (c < Parameters.MAX_CONFIDENCE) ? c : Parameters.MAX_CONFIDENCE; return this; } /** * Get the isAnalytic flag * * @return The isAnalytic value */ public boolean getAnalytic() { return analytic; } /** * Set the isAnalytic flag */ public void setAnalytic() { analytic = true; } /** * Calculate the expectation value of the truth value * * @return The expectation value */ public float getExpectation() { return (confidence * (frequency - 0.5f) + 0.5f); } /** * Calculate the absolute difference of the expectation value and that of a * given truth value * * @param t The given value * @return The absolute difference */ public float getExpDifAbs(final TruthValue t) { return Math.abs(getExpectation() - t.getExpectation()); } /** * Check if the truth value is negative * * @return True if the frequence is less than 1/2 */ public boolean isNegative() { return getFrequency() < 0.5; } public static boolean isEqual(final float a, final float b, float epsilon) { float d = Math.abs(a - b); return (d < epsilon); } /** * Compare two truth values * * @param that The other TruthValue * @return Whether the two are equivalent */ @Override public boolean equals(final Object that) { if (that instanceof TruthValue) { final TruthValue t = ((TruthValue) that); if (!isEqual(getFrequency(), t.getFrequency(), TRUTH_EPSILON)) return false; if (!isEqual(getConfidence(), t.getConfidence(), TRUTH_EPSILON)) return false; return true; } return false; } /** * The hash code of a TruthValue * * @return The hash code */ @Override public int hashCode() { return (int) (getExpectation() * 37); } @Override public TruthValue clone() { return new TruthValue(frequency, confidence, getAnalytic()); } public TruthValue setAnalytic(final boolean a) { analytic = a; return this; } /** * A simplified String representation of a TruthValue, where each factor is * accruate to 1% */ public StringBuilder appendString(final StringBuilder sb, final boolean external) { /*String s1 = DELIMITER + frequency.toStringBrief() + SEPARATOR; String s2 = confidence.toStringBrief(); if (s2.equals("1.00")) { return s1 + "0.99" + DELIMITER; } else { return s1 + s2 + DELIMITER; }*/ sb.ensureCapacity(11); return sb .append(DELIMITER) .append(Texts.n2(frequency)) .append(SEPARATOR) .append(Texts.n2(confidence)) .append(DELIMITER); } public CharSequence name() { //1 + 4 + 1 + 4 + 1 StringBuilder sb = new StringBuilder(); return appendString(sb, false); } /** output representation */ public CharSequence toStringExternal() { //return name().toString(); StringBuilder sb = new StringBuilder(); return appendString(sb, true); } /** * The String representation of a TruthValue, as used internally by the system * * @return The String */ @Override public String toString() { //return DELIMITER + frequency.toString() + SEPARATOR + confidence.toString() + DELIMITER; //1 + 6 + 1 + 6 + 1 return name().toString(); } /** displays the truth value as a short string indicating degree of true/false */ public String toTrueFalseString() { //TODO: // F,f,~,t,T return null; } /** displays the truth value as a short string indicating degree of yes/no */ public String toYesNoString() { //TODO // N,n,~,y,Y return null; } public Term toWordTerm() { float e = getExpectation(); float t = Parameters.DEFAULT_CREATION_EXPECTATION; if (e > t) { return Truth_TRUE; } if (e < 1 - t) { return Truth_FALSE; } return Truth_UNSURE; } public TruthValue set(float frequency, float confidence) { setFrequency(frequency); setConfidence(confidence); return this; } public enum TruthComponent { Frequency, Confidence, Expectation } public float getComponent(TruthComponent c) { switch (c) { case Frequency: return frequency; case Confidence: return confidence; case Expectation: return getExpectation(); } return Float.NaN; } }