Package org.rascalmpl.interpreter.matching

Source Code of org.rascalmpl.interpreter.matching.SetPattern

/*******************************************************************************
* Copyright (c) 2009-2013 CWI
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:

*   * Jurgen J. Vinju - Jurgen.Vinju@cwi.nl - CWI
*   * Emilie Balland - (CWI)
*   * Paul Klint - Paul.Klint@cwi.nl - CWI
*   * Mark Hills - Mark.Hills@cwi.nl - CWI
*   * Arnold Lankamp - Arnold.Lankamp@cwi.nl
*******************************************************************************/
package org.rascalmpl.interpreter.matching;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.eclipse.imp.pdb.facts.ISet;
import org.eclipse.imp.pdb.facts.IValue;
import org.eclipse.imp.pdb.facts.type.Type;
import org.rascalmpl.ast.Expression;
import org.rascalmpl.interpreter.IEvaluatorContext;
import org.rascalmpl.interpreter.control_exceptions.InterruptException;
import org.rascalmpl.interpreter.env.Environment;
import org.rascalmpl.interpreter.result.Result;
import org.rascalmpl.interpreter.result.ResultFactory;
import org.rascalmpl.interpreter.staticErrors.RedeclaredVariable;

public class SetPattern extends AbstractMatchingResult {
  private List<IMatchingResult> patternChildren; // The elements of the set pattern
  private int patternSize;          // Number of elements in the set pattern
  private ISet setSubject;          // Current subject 
  private Type setSubjectType;        // Type of the subject
  private Type setSubjectElementType;        // Type of the elements of current subject

  private ISet fixedSetElements;        // The fixed, non-variable elements in the pattern
  private ISet availableSetElements;      // The elements in the subject that are available:
                        // = setSubject - fixedSetElements
  /*
   * The variables are indexed from 0, ..., nVar-1 in the order in which they occur in the pattern.
   * There are three kinds:
   * - a set variable
   * - an element variable
   * - a non-literal pattern that contains variables
   */
  private int nVar;              // Number of variables
  private HashSet<String> patVars;            // List of names of variables at top-level of the pattern
  private HashMap<String,IVarPattern> allVars;// Map of names of all the variables in the pattern
                        // (including nested subpatterns)
  private String[] varName;          // Name of each variable
  private IValue[] varVal;            // Value of each variable
  private IMatchingResult[] varPat;      // The pattern value for non-literal patterns
  private boolean[] isSetVar;            // Is this a set variable?
  private boolean[] isBinding;                // Is this a binding variable occurrence?
  private boolean[] isNested;            // Is this a nested pattern?
  private Iterator<?>[] varGen;        // Value generator for this variable
 
  private int currentVar;              // The currently matched variable
    private boolean firstMatch;            // First match of this pattern?
 
  private boolean debug = false;
  private Type staticSetSubjectType;
  private Type staticSubjectElementType;
 
  public SetPattern(IEvaluatorContext ctx, Expression x, List<IMatchingResult> list){
    super(ctx, x);
    this.patternChildren = list;
    this.patternSize = list.size();
  }
 
  @Override
  public Type getType(Environment env, HashMap<String,IVarPattern> patternVars) {
    if(patternSize == 0){
      return tf.setType(tf.voidType());
    }
   
    Type elemType = tf.voidType();
    for(int i = 0; i < patternSize; i++){
      IMatchingResult child = patternChildren.get(i);
      Type childType = child.getType(env, patternVars);
      patternVars = merge(patternVars, patternChildren.get(i).getVariables());
      if(debug)System.err.println(" i = " + i + ": " + patternChildren.get(i) + ", type = " + childType);
      boolean isMultiVar = child instanceof MultiVariablePattern || child instanceof TypedMultiVariablePattern;
       
      if(childType.isSet() && isMultiVar){
        elemType = elemType.lub(childType.getElementType());
      } else {
        elemType = elemType.lub(childType);
      }
    }
    if(debug)System.err.println("SetPattern.getType: " + this + " returns " + tf.setType(elemType));
    return tf.setType(elemType);
  }
 
  @Override
  public List<IVarPattern> getVariables(){
    java.util.LinkedList<IVarPattern> res = new java.util.LinkedList<IVarPattern> ();
    for (int i = 0; i < patternChildren.size(); i++) {
      res.addAll(patternChildren.get(i).getVariables());
     }
    return res;
  }
 
  private boolean isSetVar(int i){
    return isSetVar[i];
  }
 
  // Sort the variables: element variables and non-literal patterns should
  // go before set variables since only set variables may be empty.
 
  private void sortVars(){
    String[] newVarName = new String[patternSize];
    IValue[]newVarVal= new ISet[patternSize];
    IMatchingResult[] newVarPat = new IMatchingResult[patternSize];
    boolean[] newIsSetVar = new boolean[patternSize];
    boolean[] newIsBinding = new boolean[patternSize];
    boolean[] newIsNested = new boolean[patternSize];
   
    int nw = 0;
    for(int i = 0; i < nVar; i++){
      if(!isSetVar(i)){
        newVarName[nw] = varName[i];
        newVarVal[nw] = varVal[i];
        newVarPat[nw] = varPat[i];
        newIsSetVar[nw] = isSetVar[i];
        newIsBinding[nw] = isBinding[i];
        newIsNested[nw] = isNested[i];
        nw++;
      }
    }
    for(int i = 0; i < nVar; i++){
      if(isSetVar(i)){
        newVarName[nw] = varName[i];
        newVarVal[nw] = varVal[i];
        newVarPat[nw] = varPat[i];
        newIsSetVar[nw] = isSetVar[i];
        newIsBinding[nw] = isBinding[i];
        newIsNested[nw] = isNested[i];
        nw++;
      }
    }
   
    assert nw == nVar;
    for(int i = 0; i < nVar; i++){
      varName[i] = newVarName[i];
      varVal[i] = newVarVal[i];
      varPat[i] = newVarPat[i];
      isSetVar[i] = newIsSetVar[i];
      isBinding[i] = newIsBinding[i];
      isNested[i] = newIsNested[i];
    }
  }
 
  private void printVars(){
    for(int i = 0; i < nVar; i++){
      System.err.printf("%d: %s, isSetVar=%b, isBinding=%b, isNested=%b, val=%s\n", i, varName[i], isSetVar(i), isBinding[i], isNested[i], varVal[i]);
    }
  }
 
  private boolean declaredAsSetVar(String name){
    for(int i = 0; i < nVar; i++){
      if(varName[i].equals(name))
        return isSetVar(i);
    }
    return false;
  }
 
  @Override
  public void initMatch(Result<IValue> subject) {
   
    super.initMatch(subject);
   
    if (!subject.getValue().getType().isSet()) {
      hasNext = false;
      return;
    }
   
    setSubject = (ISet) subject.getValue();
   
    if(debug) System.err.println("\n*** begin initMatch for " + this + " := " + setSubject);
   
    setSubjectType = setSubject.getType(); // have to use static type here
    staticSetSubjectType = subject.getType();
    setSubjectElementType = setSubject.getElementType();
    staticSubjectElementType = staticSetSubjectType.isSet() ? staticSetSubjectType.getElementType() : tf.valueType();
   
    if(debug)System.err.println("setSubjectType = " + setSubjectType + ", staticSetSubjectType = " + staticSetSubjectType + ", setSubjectElementType = " + setSubjectElementType + ", staticSubjectElementType =" + staticSubjectElementType);
    Environment env = ctx.getCurrentEnvt();
    //fixedSetElements = ctx.getValueFactory().set(getType(env).getElementType());
    fixedSetElements = ctx.getValueFactory().set(setSubjectElementType);
   
    nVar = 0;
    patVars = new HashSet<String>();
    allVars = new HashMap<String, IVarPattern>();
    varName = new String[patternSize];        // Some overestimations
    isSetVar = new boolean[patternSize];
    isBinding = new boolean[patternSize];
    isNested = new boolean[patternSize];
    varVal = new IValue[patternSize];
    varPat = new IMatchingResult[patternSize];
    varGen = new Iterator<?>[patternSize];
    /*
     * Pass #1: determine the (ordinary and set) variables in the pattern
     */
    for(int i = 0; i < patternSize; i++){
      IMatchingResult child = patternChildren.get(i);
      if(debug)System.err.println("child = " + child);
     
      if (child instanceof TypedMultiVariablePattern) {
        TypedMultiVariablePattern tmvVar = (TypedMultiVariablePattern) child;
        Type childType = child.getType(env, null);
        String name = tmvVar.getName();
       
        if (!tmvVar.isAnonymous() && allVars.containsKey(name)) {
          throw new RedeclaredVariable(name, getAST());
        }
       
        if(childType.comparable(staticSubjectElementType)
            || (tmvVar.bindingInstance() && childType.comparable(staticSetSubjectType))) {
          tmvVar.covertToSetType();
          if (!tmvVar.isAnonymous()) {
            patVars.add(name);
            allVars.put(name,  (IVarPattern)child);
          }
          varName[nVar] = name;
          varPat[nVar] = child;
          isSetVar[nVar] = true;
          isBinding[nVar] = true;
          isNested[nVar] = false;
          ++nVar;
        } else {
          hasNext = false;
          return;
        }
      } else if(child instanceof TypedVariablePattern){
        TypedVariablePattern patVar = (TypedVariablePattern) child;
        Type childType = child.getType(env, null);
        String name = ((TypedVariablePattern)child).getName();
        if(!patVar.isAnonymous() && allVars.containsKey(name)){
          throw new RedeclaredVariable(name, getAST());
        }
        if(childType.comparable(staticSubjectElementType)){
          /*
           * An explicitly declared set or element variable.
           */
          if(!patVar.isAnonymous()){
            patVars.add(name);
            allVars.put(name, (IVarPattern)child);
          }
          varName[nVar] = name;
          varPat[nVar] = child;
          isSetVar[nVar] = false;
          isBinding[nVar] = true;
          isNested[nVar] = false;
          nVar++;
        } else {
          hasNext = false;
          return;
          // We would like to throw new UnexpectedType(setSubject.getType(), childType, getAST());
          // but we can't do this in the context of a visit, because we might actually visit another set!
        }
       
      } else if(child instanceof MultiVariablePattern){
        /*
         * Explicitly declared set variable
         */
        MultiVariablePattern multiVar = (MultiVariablePattern) child;
        String name = multiVar.getName();

        varName[nVar] = name;
        varPat[nVar] = child;
        isSetVar[nVar] = true;
        isBinding[nVar] = true;
        isNested[nVar] = false;
        nVar++;
      } else if(child instanceof QualifiedNamePattern){
        /*
         * Use of a variable
         */
        QualifiedNamePattern qualName = (QualifiedNamePattern) child;
        String name = qualName.getName();
        if (!qualName.isAnonymous() && allVars.containsKey(name)) {
          /*
           * A set/element variable that was declared earlier in the pattern itself,
           * or in a preceding nested pattern element.
           */
          if(!patVars.contains(name)){
            /*
             * It occurred in an earlier nested subpattern.
             */
            varName[nVar] = name;
            varPat[nVar] = child;
            // If is was declared as set in the current pattern then we are sure it is a set variable,
            // otherwise we assume for now that it is not but we check this again later in matchVar.
            isSetVar[nVar] = declaredAsSetVar(name);
            isBinding[nVar] = false;
            isNested[nVar] = false;
            nVar++;
          } else {
            /*
             * Ignore it (we are dealing with sets, remember).
             */
          }
        } else if(qualName.isAnonymous()){
          varName[nVar] = name;
          varPat[nVar] = child;
          isSetVar[nVar] = false;
          isBinding[nVar] = false;
          isNested[nVar] = false;
          nVar++;
        } else  {
          /*
           * A non-anonymous variable, not seen before.
           */
          if(debug)System.err.println("Non-anonymous var, not seen before: " + name);
         
          Result<IValue> varRes = env.getVariable(name);
         
          if(varRes == null || qualName.bindingInstance()){
            // Completely new variable that was not yet declared in this pattern or its subpatterns
            varName[nVar] = name;
            varPat[nVar] = child;
            isSetVar[nVar] = false;
            isBinding[nVar] = true;
            isNested[nVar] = false;
            nVar++;
            // TODO: Why is this here? The pattern also declares the variable,
            // so this just causes errors when we use variables in set patterns.
            // env.declareVariable(staticSubjectElementType, name);
          } else {
              if(varRes.getValue() != null){
                  Type varType = varRes.getType();
                  if (varType.comparable(staticSetSubjectType)){
                    /*
                     * A set variable declared in the current scope: add its elements
                     */
                    fixedSetElements = fixedSetElements.union((ISet)varRes.getValue());
                  } else if(varType.comparable(staticSubjectElementType)){
                    /*
                     * An element variable in the current scope, add its value.
                     */
                    fixedSetElements = fixedSetElements.insert(varRes.getValue());
                  } else {
                    hasNext = false;
                    return;
                    // can't throw type error: throw new UnexpectedType(staticSetSubjectType,varType, getAST());
                  }
              }
              else {
                // Support pre-declared set variables
             
                if(varRes.getType().comparable(staticSetSubjectType) || varRes.getType().comparable(staticSubjectElementType)){
                /*
                 * An explicitly declared set or element variable.
                 */
                if(!name.equals("_")){
                  patVars.add(name);
                  allVars.put(name, (IVarPattern) child);
                }
                varName[nVar] = name;
                varPat[nVar] = child;
                isSetVar[nVar] = varRes.getType().isSet();
                isBinding[nVar] = false;
                isNested[nVar] = false;
                nVar++;
                }
              }
            }
        }
      } else if(child instanceof LiteralPattern){
        /*
         * A literal pattern: add it to the set of fixed element
         */
        IValue lit = ((LiteralPattern) child).toIValue(env);
        Type childType = child.getType(env, null);
        if(!childType.comparable(staticSubjectElementType)){
//          throw new UnexpectedType(setSubject.getType(), childType, getAST());
          hasNext = false;
          return;
        }
        fixedSetElements = fixedSetElements.insert(lit);
        if(debug)System.err.println("fixedSetElements => " + fixedSetElements);
      } else {
        /*
         * All other cases of a nested pattern that is not a variable or a literal.
         */
        Type childType = child.getType(env, null);
        if(!childType.comparable(staticSubjectElementType)){
          hasNext = false;
          return;
          // can't throw type error: throw new UnexpectedType(setSubject.getType(), childType, getAST());
        }
        java.util.List<IVarPattern> childVars = child.getVariables();
        if(!childVars.isEmpty()){
          boolean varIntro = false;
          for(IVarPattern vp : childVars){
            if(debug) System.err.println("var =" + vp);
            IVarPattern prev = allVars.get(vp.name());
            boolean vpVarIntro = vp.isVarIntroducing();
            varIntro = varIntro || vpVarIntro;
            if(prev == null || vpVarIntro)
              allVars.put(vp.name(), vp);
          }
          varName[nVar] = child.toString();
          varPat[nVar] = child;
          isSetVar[nVar] = false;
          isBinding[nVar] = varIntro;
          isNested[nVar] = true;
          nVar++;
        } else {
          // A nested pattern without variables: treat it as a literal
          fixedSetElements = fixedSetElements.insert(child.toIValue());
          if(debug)System.err.println("fixedSetElements => " + fixedSetElements);
        }
      }
    }
    /*
     * Pass #2: set up subset generation
     */
    firstMatch = true;
    hasNext = fixedSetElements.isSubsetOf(setSubject);
    if(debug){
      System.err.println("fixedSetElements => " + fixedSetElements);
      System.err.println("setSubject => " + setSubject);
    }
    availableSetElements = setSubject.subtract(fixedSetElements);
    sortVars();
    if(debug){
      System.err.println("Pattern " + this);
      printVars();
      System.err.printf("hasNext = %b\n", hasNext);
      System.err.println("FixedSetElements: " + fixedSetElements);
      System.err.println("availableSetElements: " + availableSetElements);
      if(debug) System.err.println("*** end initMatch for " + this + "\n");
    }
  }
 
  @Override
  public boolean hasNext(){
    return initialized && hasNext;
  }
 
  /**
   * @return the remaining subject set elements that are available to be matched
   */
  private ISet available(){
    ISet avail = availableSetElements;
    for(int j = 0; j < currentVar; j++){
      if(isSetVar(j)){
        if(varVal[j] != null)
          avail = avail.subtract((ISet)varVal[j]);
      } else {
        if(varVal[j] != null)
          avail = avail.delete(varVal[j]);
      }
    }
    return avail;
  }
 
  private boolean unexploredAlternatives(){
    assert currentVar == nVar;
    for(int j = 0; j < nVar; j++){
      if(isSetVar(j)){
        if(varGen[j].hasNext())
          return true;
      } else if(isNested[j] && varPat[j].hasNext())
        return true;
    }
    return false;
  }
 
 
  /**
   * Create a value generator for variable i.
   * @param i      the variable
   * @param elements  set elements that may be assigned to it
   * @return      whether creation succeeded
   */
  private boolean makeGen(int i, ISet elements) {
    if(debug) System.err.println("makeGen: " + i +", " + elements);
   
    Environment env = ctx.getCurrentEnvt();
   
    if(varPat[i] instanceof QualifiedNamePattern){
      QualifiedNamePattern qualName = (QualifiedNamePattern) varPat[i];
      String name = qualName.getName();
      // Binding occurrence of this variable?
      if(isBinding[i] || qualName.isAnonymous() || env.getVariable(name) == null || env.getVariable(name).getValue() == null){
        if(isSetVar(i)){
          varGen[i] = new SubSetGenerator(elements, ctx);
        } else {
          if(elements.size() == 0)
            return false;
          varGen[i] = new SingleElementIterator(elements, ctx);
        }
      } else {
        // Variable has been set before, use its dynamic type to distinguish set variables.
        IValue val = env.getVariable(name).getValue();
       
        if (val != null) {
          if (val != null && val.getType().isSet()){
            isSetVar[i] = true;
            if(elements.equals(val)){
              varGen[i] = new SingleIValueIterator(val);
              return true;
            }
            return false;
          }
          if (elements.contains(val)){
            varGen[i] = new SingleIValueIterator(val);
          } else {
            return false;
          }
        }
      }
      return true;
    }
   
    if(isSetVar(i)){
      varGen[i] = new SubSetGenerator(elements, ctx);
      return true;
    }
    if(elements.size() == 0)
      return false;
    varGen[i] = new SingleElementIterator(elements, ctx);
    return true;
  }
 
  @Override
  public boolean next(){
    checkInitialized();
   
    if(!hasNext)
      return false;
   
    if(firstMatch){
      firstMatch = hasNext = false;
      if(nVar == 0){
        return fixedSetElements.isEqual(setSubject);
      }
      if(!fixedSetElements.isSubsetOf(setSubject)){
        return false;
      }
     
      if(patternSize == 1){
        if(isSetVar(0) || availableSetElements.size() == 1) {
          IValue elem ;
          if(isSetVar(0)){
            // Var #i is a set variable: should match all elements
            varVal[0] = (ISet) availableSetElements;
            elem = availableSetElements;
          }
          else {
            // Var #i is not a set variable.
            if(availableSetElements.getType().isSet()){
              // Var #i should match single element in elements
              ISet set = (ISet) availableSetElements;
              assert set.size() == 1;
              varVal[0] = elem = set.iterator().next();
            } else {
              varVal[0] = elem = availableSetElements;
              //varVal[i] = ctx.getValueFactory().set(elem.getType()).insert(elem); // TODO: Should this be  a set?
            }
          }

          varPat[0].initMatch(ResultFactory.makeResult(elem.getType(), elem, ctx));
          hasNext = varPat[0].hasNext();
        }
      }
     
      currentVar = 0;
      if(!makeGen(currentVar, availableSetElements)){
        return false;
      }
    } else {
      currentVar = nVar - 1;
    }
    hasNext = true;

    if(debug)System.err.println("\nStart assigning Vars for " + this + ":= " + subject);

    if (patternSize == 1 && (isSetVar(0) || availableSetElements.size() == 1)) {
      if (varPat[0].hasNext() && varPat[0].next()) {
        return true;
      }
     
      return false;
    }
   
    main:
    do {
      if (ctx.isInterrupted()) {
        throw new InterruptException(ctx.getStackTrace(), ctx.getCurrentAST().getLocation());
      }
     
      if(debug)System.err.println("\n=== MAIN: Pattern = " + this ":= " + subject + "\ncurrentVar[" + currentVar + "]=" + varName[currentVar]);
      if(debug)printVars();
      IValue v = null;
      boolean b = false;
      if(isNested[currentVar]){
        if(varPat[currentVar].hasNext()){
          b = varPat[currentVar].next();
          if(b)
            v = varVal[currentVar];
        } else if(varGen[currentVar].hasNext()){
          v = (IValue) varGen[currentVar].next();
          Result<IValue> r = ResultFactory.makeResult(v.getType(), v, ctx);
          varPat[currentVar].initMatch(r);
          b = varPat[currentVar].next();
          if(b)
            varVal[currentVar] = v;
        }
      } else if(isSetVar[currentVar]){
          if(varGen[currentVar].hasNext()){
            v = (IValue) varGen[currentVar].next();
            Result<IValue> r = ResultFactory.makeResult(v.getType().lub(setSubjectType), v, ctx);
            varPat[currentVar].initMatch(r);
            b = varPat[currentVar].next();
            if(b){
              varVal[currentVar] = v;
              ctx.getCurrentEnvt().storeVariable(varName[currentVar], r);
              if(debug)System.err.println("Store in " + varName[currentVar] + ": " + r + " / " + v + " / " + v.getType() + " / " +
              ctx.getCurrentEnvt().getVariable(varName[currentVar]).getType());
            }
          }
      } else if(isBinding[currentVar]){
        if(varGen[currentVar].hasNext()){
          v = (IValue) varGen[currentVar].next();
         
          Result<IValue> r = ResultFactory.makeResult(v.getType(), v, ctx);
          varPat[currentVar].initMatch(r);
          b = varPat[currentVar].next();
          if(b){
            varVal[currentVar] = v;
            ctx.getCurrentEnvt().storeVariable(varName[currentVar], r);
            if(debug)System.err.println("Store in " + varName[currentVar] + ": " + r + " / " + v + " / " + v.getType() + " / " +
                ctx.getCurrentEnvt().getVariable(varName[currentVar]).getType());
          }
        }
      } else   if(varPat[currentVar] instanceof QualifiedNamePattern && ((QualifiedNamePattern)varPat[currentVar] ).isAnonymous()){
          if(varGen[currentVar].hasNext()){
            v = (IValue) varGen[currentVar].next();
            Result<IValue> r = ResultFactory.makeResult(v.getType(), v, ctx);
            varPat[currentVar].initMatch(r);
            b = varPat[currentVar].next();
            if(b){
              varVal[currentVar] = v;
            }
          }
      } else if(!isBinding[currentVar] && (varPat[currentVar] instanceof QualifiedNamePattern || varPat[currentVar] instanceof TypedVariablePattern&& varGen[currentVar].hasNext()){
          v = (IValue) varGen[currentVar].next();
          Result<IValue> r = ResultFactory.makeResult(v.getType(), v, ctx);
          varPat[currentVar].initMatch(r);
          b = varPat[currentVar].next();
          System.err.println("Try match " + varName[currentVar] + ": " + r + " / " + v + " / " + v.getType());
          if(b){
            varVal[currentVar] = v;
            System.err.println("Matches " + varName[currentVar] + ": " + r + " / " + v + " / " + v.getType());
          }
       
      } else {
       
        System.err.println("CANNOT HANDLE THIS 2");
      }
     
      //if(debug) System.err.println("currentVar[" + currentVar + "] = " +  varName[currentVar] + "; v = " + v + "; type: " + v.getType() + "; matchPatternElement = " + b);
      if(b){
        currentVar++;
        ISet avail = available();
        if(currentVar <= nVar - 1){
          if(!makeGen(currentVar, avail)){
            varGen[currentVar] = null;
            currentVar--;
          }
          continue main;
        } else {
          if(!avail.isEmpty()){
            if(debug)System.err.println("nomatch: currentVar = " + currentVar + " avail = " + available());
            currentVar--;
            continue main;
          }
          hasNext = unexploredAlternatives();
          if(debug) System.err.println("currentVar > nVar -1\n" + this + ":= " + subject + " returns true, hasNext = " + hasNext + ", available = " + available());
          return true;
        }
       
      }
      if(!varGen[currentVar].hasNext()){
        varGen[currentVar] = null;
        currentVar--;
      }
      if(debug)System.err.println("currentVar becomes: " + currentVar);
      continue main;
    } while(currentVar >= 0 && currentVar < nVar);


    if(currentVar < 0){
      hasNext = false;
      if(debug) System.err.println("Pattern " + this + " := " + subject + " returns false");
      return false;
    }
    hasNext = unexploredAlternatives();
    if(debug) System.err.println("Pattern " + this " := " + subject + " returns true, hasNext = " + hasNext + ", available = " + available());
    return available().isEmpty();
 
 
  @Override
  public String toString(){
    StringBuilder res = new StringBuilder();
    res.append("{");
    String sep = "";
    for (IBooleanResult mp : patternChildren){
      res.append(sep);
      sep = ", ";
      res.append(mp.toString());
    }
    res.append("}");
   
    return res.toString();
  }
}
TOP

Related Classes of org.rascalmpl.interpreter.matching.SetPattern

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.