Package ket.math

Source Code of ket.math.KnownArguments

/*
* Copyright (C) 2011  Alasdair C. Hamilton
*
* This program 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 3 of the License, or
* (at your option) any later version.
*
* This program 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 this program.  If not, see <http://www.gnu.org/licenses/>
*/

package ket.math;

import java.util.*;

import ket.math.purpose.CompoundState;
import ket.math.purpose.SymbolicState;
import ket.math.purpose.VariableState;
import ket.math.purpose.Word;
import ketUI.Ket;

/**
* This contains user-defined variables and functions inferred from previous
* use are recorded here for future reference such as to auto-complete user
* input.
*/
public class KnownArguments {

  public static final Comparator<String> STRING_LENGTH_COMPARATOR = new LengthComparator();

  /**
   * Store all known functions that will be used in the given equation.
   */
  Set<Function> functionSet;
 
  /**
   * Some symbols are available as states of tokens and for the sake of
   * auto-completion, these are stored here.
   */
  Set<Symbol> operandSymbolSet;

  /**
   * Word tokens excluding quoted text.
   */
  Set<String> variableNameStringSet;

  /**
   * A collection of all variables that are represented by symbols.
   */
  Set<State> variableState;

  /**
   * A map from the name of a symbol to its instance.
   */
  Vector<Symbol> allSymbols;
 
  HashMap<Character, Function> charToFunctionMap;

  public KnownArguments(Collection<Symbol> operandSymbolSet, Collection<Function> defaultOperators, Collection<Symbol> allSymbols, Map<Character,Function> defaultCharToFunctionMap) {
    // Create a shallow copy of the function list as it will be
    // modified.
    functionSet = new HashSet<Function>()
    this.operandSymbolSet = new HashSet<Symbol>(operandSymbolSet);
    //- operandSymbolSet.addAll(Symbol.DEFAULT_OPERAND_SYMBOLS);
    //- operandSymbolSet.addAll(Symbol.GREEK_LETTERS);
    variableState = new HashSet<State>();
    variableNameStringSet = new HashSet<String>();
    //- for (Function function : Function.DEFAULT_OPERATORS) {
    for (Function function : defaultOperators) {
      recordUniqueFunction(function);
    }
    this.allSymbols = new Vector<Symbol>();
    //- allSymbols.addAll(Symbol.ALL_SYMBOLS);
    this.allSymbols.addAll(allSymbols);
    //- charToFunctionMap = new HashMap<Character, Function>(Type.DEFAULT_CHAR_TO_FUNCTION_MAP);
    charToFunctionMap = new HashMap<Character,Function>(defaultCharToFunctionMap);
  }

  public void recordVariable(State state) {
    if (state instanceof Word) {
      Word word = (Word) state;
      String name = word.getValue();
      recordUniqueVariable(name);
    } else {
      recordUniqueVariable(state);
    }
  }


  /**
   * Find a symbol by its associated digraph consisting two characters.
   */
  public Symbol getDigraph(String digraph) {
    Ket.out.println(" --- known arguments::get digraph --- ");
    Ket.out.println("\tdigraph = '"+digraph+"'");

    for (Symbol symbol: allSymbols) {
      String[] digraphArray = symbol.getDigraphs();
      for (int i=0; i<digraphArray.length; i++) {
        if (digraphArray[i].equals(digraph)) {
          return symbol;
        }
      }
    }

    // otherwise:
    Ket.out.println(" !!! Unknown !!! ");
    return Symbol.UNKNOWN;
  }

  /**
   * Convert a given function to a corresponding state, keeping a record
   * of it as appropriate.
   */
  public VariableState functionToState(Function function) {
    if (function==null) return null;
    if (function instanceof SymbolicFunction) {
      SymbolicFunction symbolicFunction = (SymbolicFunction) function;
      VariableState state = null;
      if (symbolicFunction.isPrefixOnly()) {
        state = (VariableState) symbolicFunction.getPrefix();
        addState(state);
      } else {
        Ket.out.println(" !!! The only functions that can be converted to variables are prefix-only !!! ");
      }
      return state;
    } else {
      String name = function.getName();
      recordUniqueVariable(name);
      return new Word(name);
    }
  }

  public State toState(Purpose purpose) {
    if (purpose instanceof Function) {
      return (State) functionToState((Function) purpose);
    } else {
      return (State) purpose;
    }
  }

  public Function toFunction(Purpose purpose) {
    if (purpose instanceof Function) {
      return (Function) purpose;
    } else {
      return stateToFunction((State) purpose);
    }
  }

  public Function stateToFunction(State state) {
    if (state==null) {
      return null;
    } else if ( ! (state instanceof VariableState) ) {
      Ket.out.println(" !!! cannot convert state to a function !!! ");
      Ket.out.println("state = " + state + ", " + state.getClass());
      return null;
    } else if (state instanceof Word) {
      String pattern = ((Word) state).getValue();
      return recordUniqueFunction(pattern);
    } else if (state instanceof SymbolicState) {
      SymbolicState prefixState = (SymbolicState) state;
      SymbolicFunction symbolicFunction = new SymbolicFunctionBuilder(
          prefixState.getName(),
          Children.ANY_NUMBER_OF_CHILDREN,
          Function.DEFAULT_PRECEDENCE)
        .setPrefix(prefixState)
        .setShowBrackets()
        .build();
      return recordUniqueFunction(symbolicFunction);
    } else {
      return null;
    }
  }


  // ------------------------------------------------------------------------

  /**
   * Given the start of an argument's name, return the a Vector of
   * possible argument names that begin with this string.  Selection can
   * be restricted with appropriate flags (FUNCTIONS, TOKENS or ALL).
   */
  public Vector<String> autocompleteArgumentNames(String startOfName, char initialCharacter) {
    SortedSet<String> suggestions = new TreeSet<String>(STRING_LENGTH_COMPARATOR);

    for (Function function : functionSet) {
      boolean matchTypeChar = function.matchTypeChar(initialCharacter);
      String name = function.getName();
      boolean nameStartMatches = name.startsWith(startOfName);
      if (matchTypeChar && nameStartMatches) {
        suggestions.add(function.getFullName()); // &fraction
        //- suggestions.add(function.getName()); // fraction  // WARNING: Auto complete integral gets stuck on \integral without &.
      }
    }

    for (String name : variableNameStringSet) {
      if (name.startsWith(startOfName)) {
        suggestions.add(name);
      }
    }

    for (State state : variableState) {
      String name = state.toString();
      if (name.startsWith(startOfName)) {
        suggestions.add(state.getFullName());
      }
    }

    // Search known symbols, e.g. \alpha etc.
    for (Symbol symbol : operandSymbolSet) {
      boolean matchTypeChar = symbol.matchTypeChar(initialCharacter);
      String name = symbol.getName();
      boolean nameStartMatches = name.startsWith(startOfName);
      String word = symbol.getWord();
      boolean wordStartMatches = word.startsWith(startOfName);
      if (matchTypeChar && nameStartMatches && wordStartMatches) {
        suggestions.add(symbol.getFullName());
      }
    }

    Ket.out.println("    suggestions = " + suggestions + " <--------------- " );
    return new Vector<String>(suggestions);
  }


  ////////////////////////////////////////////////////////////////////////////////

  // TODO: Transforming form a set to a sorted list every time is
  // impractical: use some kind of sorted set for concision. 
  public Vector<Function> getSortedFunctions() {
    Vector<Function> sortedFunctions = new Vector<Function>(functionSet);
    Collections.sort(sortedFunctions);
    return sortedFunctions;
  }

  public Vector<SymbolicFunction> getSortedSymbolicFunctions() {
    Vector<SymbolicFunction> sortedSymbolicFunctions = new Vector<SymbolicFunction>();
    for (Function function : functionSet) {
      if (function instanceof SymbolicFunction) {
        sortedSymbolicFunctions.add((SymbolicFunction) function);
      }
    }
    Collections.sort(sortedSymbolicFunctions);
    return sortedSymbolicFunctions;
  }

  // Used in equation reading next symbol when tokenizing.
  public Set<Symbol> getOperandSymbolSet() {
    return operandSymbolSet;
  }

  /**
   * Search through the list of existing function names for one in which
   * its name '.equals()' the string argument.
   */
  public Function matchExistingFunction(String name) {
    Vector<Function> matches = new Vector<Function>();
    for (Function function : functionSet) {
      if (function.getName().equals(name)) {
        matches.add(function);
      }
    }
    assert matches.size()<=1 : "Multiple functions of the same name were found.";
    return matches.size()==1 ? matches.firstElement() : null;
  }

  /**
   * Search for a given function that has exactly the same name, and if
   * it does not exist, then create and add it.
   */
  public Function recordUniqueFunction(String name) {
    Function existingFunction = matchExistingFunction(name);
    if (existingFunction!=null) {
      return existingFunction;
    }
    Function function = new NamedFunction(name, Children.ANY_NUMBER_OF_CHILDREN);
    recordUniqueFunction(function);
    return function;
  }

  /**
   * Keep a record of all known functions and if it is a symbolic
   * function then also record the constituent symbols.
   */
  private Function recordUniqueFunction(Function function) {
    for (Function next : functionSet) {
      // Search for an existing version of the function.
      if (next.equals(function)) {
        Ket.out.println("!!! function already found !!! ");
        Ket.out.println("old function = " + next.toString() + ", " + next.getName());
        Ket.out.println("new function = " + function.toString() + ", " + function.getName());
        Ket.out.println("");
        return next;
      }
    }

    // Otherwise the functions must be new.
    functionSet.add(function);
    if (function instanceof SymbolicFunction) {
      SymbolicFunction symbolicFunction = (SymbolicFunction) function;
      Vector<SymbolicState> stateVector = symbolicFunction.getSymbolicStates();
      for (SymbolicState state : stateVector) {
        if (state instanceof Symbol) {
          addState((Symbol) state);
        } else if (state instanceof CompoundState) {
          addState((CompoundState) state);
        }
      }
    }
    return function;
  }



  // -------------------------------------------------------------------------------------------------------

  //////////////////////////
  // TODO: CLEAN UP.      //
  //////////////////////////

  /**
   * Record any variable names in order to perform auto-complete and
   * intelligent string matching.
   */
  public void recordUniqueVariable(String variableName) {
    variableNameStringSet.add(variableName);
  }

  public void recordUniqueVariable(State state) {
    variableState.add(state);
  }

  private void addState(Symbol symbol) { // ?
    operandSymbolSet.add(symbol);
  }

  // -------------------------------------------------------------------------------------------------------


  private void addState(CompoundState compoundState) {
    // TODO: Should this method's application be restricted to one
    // of either states of functions or states of variables?
    String name = compoundState.getName();
    recordUniqueVariable(name);
  }
  private void addState(VariableState variableState) {
  }

  /**
   * Return a function defined by a corresponding character.
   */
  public Function getFunctionByChar(char character) { 
    return charToFunctionMap.get(character);
  }

  /**
   * Return a quick summary of the known tokens and functions.
   */
  public String toString() {
    String string = "";
    string += "function set:\n";
    string += functionSet;
    string += "\n\n";

    string += "operandSymbolSet:\n";
    string += operandSymbolSet;
    string += "\n\n";

    string += "variableNameStringSet:\n";
    string += variableNameStringSet;
    string += "\n\n";

    string += "variableState:\n";
    string += variableState;
    string += "\n\n";

    string += "allSymbols:\n";
    string += allSymbols;
    string += "\n\n";

    string += "charToFunctionMap:\n";
    string += charToFunctionMap;
    return string;
  }


}
TOP

Related Classes of ket.math.KnownArguments

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.