Exemple #1
0
/* A trail slot is marked iff it contains
   an unbound constrained variable reference or a goal.
*/
static CVOID__PROTO(markChoicepoints) {
  /* Mark choicepoints and corresponding chains of frames */
  /* and mark remaining trail entries */
  node_t *cp = Gc_Aux_Node;
  tagged_t *tr = w->trail_top;
  tagged_t *limit;

  while (ChoiceYounger(cp,Gc_Choice_Start))
    {
      intmach_t n = cp->next_alt->node_offset;
      intmach_t i = OffsetToArity(n);

      markFrames(Arg, cp->frame, cp->next_insn);
      while ((i--)>0)
	{
	  if (IsHeapTerm(cp->term[i]))
	    markVariable(Arg, &cp->term[i]);
	}
      cp = ChoiceCharOffset(cp, -n);

      /* mark goals and unbound constrained variables;
	 reset unmarked bound variables
	 between cp->trail_top and tr */

      limit = TagToPointer(cp->trail_top);
      while (TrailYounger(tr,limit))
	{
	  tagged_t v = TrailPop(tr);
	
	  if (v==(tagged_t)NULL || gc_IsMarked(v))
	    ;
	  else if (!IsVar(v))
	    markVariable(Arg, tr);
#ifdef EARLY_RESET
	  else if (TagIsCVA(v))
	    {
	      if (!gc_IsMarked(*TagToCVA(v)))
		*TagToCVA(v)= v, markVariable(Arg, tr), *tr= 0;
	    }
	  else
	    {
	      if (!gc_IsMarked(*TagToPointer(v)))
		*TagToPointer(v)= v, *tr= 0;
	    }
#else
	  else if (TagIsCVA(v))
	    markVariable(Arg, tr);
#endif
	}
    }
Exemple #2
0
TokenTypes CMathParser::NextToken()//{ Gets the next Token from the Input stream }
{
	CSPString NumString;// : String[80];
	WORD TLen, NumLen; //, FormLen, Place;
	// int Check ;//: Integer;
	char Ch;//, FirstChar;
	BOOL Decimal ;
	TokenTypes ResultNextToken;

	while ((Position < FInput.GetLength()) && (FInput.GetAt(Position) == ' '))
		Position++;
	TokenLen = Position;
	if (Position >= FInput.GetLength())
	{
		ResultNextToken = EOL;
		TokenLen = 0;
		return ResultNextToken;
	}

	FInput.MakeUpper();

	Ch = FInput.GetAt(Position);
	if (Ch== '!')
	{
		ResultNextToken = ERR;
		TokenLen = 0;
		return ResultNextToken ;
	}

	if((Ch >= '0' && Ch <= '9') || Ch == '.')//   if Ch in ['0'..'9', '.'] then
	{
		NumString = "";
		TLen = Position;
		Decimal = FALSE;

		while ((TLen < FInput.GetLength()) &&
			((FInput.GetAt(TLen) >= '0' && FInput.GetAt(TLen) <= '9' ) ||
			((FInput.GetAt(TLen) == '.') && (!Decimal)))) 
		{
			NumString = NumString + FInput.GetAt(TLen);
			if (Ch == '.')// then
				Decimal = TRUE;
			TLen++;//Inc(TLen);
		}

		if ((TLen == 2) && (Ch == '.'))// then
		{
			ResultNextToken = BAD;
			TokenLen = 0;
			return ResultNextToken ;
		}

		if ((TLen < FInput.GetLength()) && ((FInput.GetAt(TLen)) == 'E'))// then
		{
			NumString = NumString + 'E';
			TLen++;
   
			if( FInput.GetAt(TLen) == '+' || FInput.GetAt(TLen) == '-')// in ['+', '-'] then
			{
				NumString.SetAt(TLen, FInput.GetAt(TLen));//= NumString + FInput[TLen];
				TLen++;
			}

			NumLen = 1;
			while ((TLen < FInput.GetLength()) && (FInput.GetAt(TLen) >= '0' && FInput.GetAt(TLen) <= '9') &&
				 (NumLen <= MP_MaxExpLen)) 
			{
				NumString = NumString + FInput.GetAt(TLen);
				NumLen++;//Inc(NumLen);
				TLen++;//Inc(TLen);
			}
		}

		if (NumString[0] == '.')// then
			NumString = '0' + NumString;

		CurrToken.Value = atof(NumString);
		//Val(NumString, CurrToken.Value, Check);

		/*//if (Check != 0 )
		{//    begin
			ErrorCode = MP_ErrMath;
			ErrorCode = ErrInvalidNum;
			Position += Pred(Check);
			//Inc(Position, Pred(Check));
		}//  end { if }
		else*/
		{//  begin
			ResultNextToken = NUM;
			Position += NumString.GetLength();
			//Inc(Position, System.Length(NumString));
			TokenLen = Position - TokenLen;
		}// end; { else }
		return ResultNextToken;
	}//end { if }
	else if ((Ch>='a' && Ch <= 'z')
	   || (Ch>='A' && Ch <= 'Z'))//in Letters then
	{//   begin
		if (IsFunc("ABS") ||
			IsFunc("ATAN") ||
			IsFunc("COS") ||
			IsFunc("EXP") ||
			IsFunc("LN") ||
			IsFunc("ROUND") ||
			IsFunc("SIN") ||
			IsFunc("SQRT") ||
			IsFunc("SQR") ||
			IsFunc("TRUNC")||
			IsFunc("NOT")||// then//EXPAND
			IsFunc("BOOL")||
			IsFunc("SGN")
			)
		{
			ResultNextToken = FUNC;
			TokenLen = Position - TokenLen;
			return ResultNextToken ;
		}

		if (IsFunc("MOD")) 
		{
			ResultNextToken = MODU;
			TokenLen = Position - TokenLen;
			return ResultNextToken ;
		}
		if (IsVar(CurrToken.Value))
		{
			ResultNextToken = NUM;
			TokenLen = Position - TokenLen;
			return ResultNextToken;
		}
		else 
		{
			ResultNextToken = BAD;
			TokenLen = 0;
			return ResultNextToken ;
		}
	}
	else 
	{//   begin
		switch(Ch)
		{
		case  '+' : ResultNextToken = PLUS; break;
		case  '-' : ResultNextToken = MINUS; break;
		case  '*' : ResultNextToken = TIMES; break;
		case  '/' : ResultNextToken = DIVIDE; break;
		case  '^' : ResultNextToken = EXPO; break;
		case  '(' : ResultNextToken = OPAREN; break;
		case  ')' : ResultNextToken = CPAREN; break;
		default:
		 ResultNextToken = BAD;
		 TokenLen = 0;
		 return ResultNextToken ;
	}//end; { case }
	Position++;
	TokenLen = Position - TokenLen;
	return ResultNextToken ;
	}//end; { else if }
}//end; { NextToken }
/*-------------------------------------------------------------------------*
 * SIMPLIFY                                                                *
 *                                                                         *
 * This function returns the result of the simplified boolean expression   *
 * given in e_word. NOT operators are only applied to variables.           *
 *                                                                         *
 * Input:                                                                  *
 *    sign  : current sign of the boolean term (-1 (inside a ~) or +1)     *
 *    e_word: boolean term to simplify                                     *
 *                                                                         *
 * Output:                                                                 *
 *    The returned result is a pointer to a node of the following form:    *
 *                                                                         *
 *    for binary boolean not operator (~):                                 *
 *        [1]: variable involved (tagged word)                             *
 *        [0]: operator NOT                                                *
 *                                                                         *
 *    for unary boolean operators (<=> ~<=> ==> ~==> /\ ~/\ \/ ~\/):       *
 *        [2]: right boolean exp (pointer to node)                         *
 *        [1]: left  boolean exp (pointer to node)                         *
 *        [0]: operator (EQUIV, NEQUIV, IMPLY, NIMPLY, AND, NAND, OR, NOR) *
 *                                                                         *
 *    for boolean false value (0):                                         *
 *        [0]: ZERO                                                        *
 *                                                                         *
 *    for boolean true value (1):                                          *
 *        [0]: ONE                                                         *
 *                                                                         *
 *    for boolean variable:                                                *
 *        [0]: tagged word                                                 *
 *                                                                         *
 *    for binary math operators (= \= < >= > <=) (partial / full AC):      *
 *        [2]: right math exp (tagged word)                                *
 *        [1]: left  math exp (tagged word)                                *
 *        [0]: operator (EQ, NEQ, LT, LTE, EQ_F, NEQ_F, LT_F, LTE_F)       *
 *             (GT, GTE, GT_F, and GTE_F becomes LT, LTE, LT_F and LTE_F)  *
 *                                                                         *
 * These nodes are stored in a hybrid stack. NB: XOR same as NEQUIV        *
 *-------------------------------------------------------------------------*/
static WamWord *
Simplify(int sign, WamWord e_word)
{
  WamWord word, tag_mask;
  WamWord *adr;
  WamWord f_n, le_word, re_word;
  int op, n;
  WamWord *exp, *sp1;
  WamWord l, r;

#ifdef DEBUG
  printf("ENTERING %5ld: %2d: ", sp - stack, sign);
  Pl_Write(e_word);
  printf("\n");
#endif

  exp = sp;

  if (sp - stack > BOOL_STACK_SIZE - 5)
    Pl_Err_Resource(pl_resource_too_big_fd_constraint);

  DEREF(e_word, word, tag_mask);
  if (tag_mask == TAG_REF_MASK || tag_mask == TAG_FDV_MASK)
    {
      adr = UnTag_Address(word);
      if (vars_sp - vars_tbl == VARS_STACK_SIZE)
	Pl_Err_Resource(pl_resource_too_big_fd_constraint);

      *vars_sp++ = word;
      *vars_sp++ = 0;		/* bool var */

      if (sign != 1)
	*sp++ = NOT;

      *sp++ = Tag_REF(adr);
      return exp;
    }

  if (tag_mask == TAG_INT_MASK)
    {
      n = UnTag_INT(word);
      if ((unsigned) n > 1)
	goto type_error;

      *sp++ = ZERO + ((sign == 1) ? n : 1 - n);
      return exp;
    }

  if (tag_mask == TAG_ATM_MASK)
    {
      word = Pl_Put_Structure(ATOM_CHAR('/'), 2);
      Pl_Unify_Value(e_word);
      Pl_Unify_Integer(0);
    type_error:
      Pl_Err_Type(pl_type_fd_bool_evaluable, word);
    }


  if (tag_mask != TAG_STC_MASK)
    goto type_error;

  adr = UnTag_STC(word);

  f_n = Functor_And_Arity(adr);
  if (bool_xor == f_n)
    op = NEQUIV;
  else
    {
      for (op = 0; op < NB_OF_OP; op++)
	if (bool_tbl[op] == f_n)
	  break;

      if (op == NB_OF_OP)
	{
	  word = Pl_Put_Structure(ATOM_CHAR('/'), 2);
	  Pl_Unify_Atom(Functor(adr));
	  Pl_Unify_Integer(Arity(adr));
	  goto type_error;
	}
    }

  le_word = Arg(adr, 0);
  re_word = Arg(adr, 1);

  if (op == NOT)
    return Simplify(-sign, le_word);

  if (sign != 1)
    op = (op % 2 == EQ % 2) ? op + 1 : op - 1;

  if (op >= EQ && op <= LTE_F)
    {
      Add_Fd_Variables(le_word);
      Add_Fd_Variables(re_word);

      n = (op == GT || op == GT_F) ? op - 2 :
	(op == GTE || op == GTE_F) ? op + 2 : op;

      *sp++ = n;
      *sp++ = (n == op) ? le_word : re_word;
      *sp++ = (n == op) ? re_word : le_word;
      return exp;
    }

  sp += 3;
  exp[0] = op;
  exp[1] = (WamWord) Simplify(1, le_word);
  sp1 = sp;
  exp[2] = (WamWord) Simplify(1, re_word);

  l = *(WamWord *) (exp[1]);
  r = *(WamWord *) (exp[2]);

  /* NB: beware when calling below Simplify() (while has been just called above)
   * this can ran into stack overflow (N^2 space complexity). 
   * Try to recover the stack before calling Simplify().
   * Other stack recovery are less important (e.g. when only using exp[1]).
   *
   * In the following exp[] += sizeof(WamWord) is used to "skip" the NOT
   * in a simplification (points to the next cell).
   */

  switch (op)
    {
    case EQUIV:
      if (l == ZERO)		/* 0 <=> R is ~R */
	{
	  sp = exp;
	  return Simplify(-1, re_word);
	}

      if (l == ONE)		/* 1 <=> R is R */
	{
	  return (WamWord *) exp[2];
	}

      if (r == ZERO)		/* L <=> 0 is ~L */
	{
	  sp = exp;
	  return Simplify(-1, le_word);
	}

      if (r == ONE)		/* L <=> 1 is L */
	{
	  sp = sp1;
	  return (WamWord *) exp[1];
	}

      if (l == NOT)		/* ~X <=> R is X <=> ~R */
	{
	  exp[1] += sizeof(WamWord); 
	  sp = sp1;
	  exp[2] = (WamWord) Simplify(-1, re_word);
	  break;
	}

      if (r == NOT)		/* L <=> ~X is ~L <=> X */
	{			/* NB: cannot recover the stack */	  
	  exp[1] = (WamWord) Simplify(-1, le_word);
	  exp[2] += sizeof(WamWord);
	  break;
	}
      break;

    case NEQUIV:
      if (l == ZERO)		/* 0 ~<=> R is R */
	{
	  return (WamWord *) exp[2];
	}

      if (l == ONE)		/* 1 ~<=> R is ~R */
	{
	  sp = exp;
	  return Simplify(-1, re_word);
	}

      if (r == ZERO)		/* L ~<=> 0 is L */
	{
	  sp = sp1;
	  return (WamWord *) exp[1];
	}

      if (r == ONE)		/* L ~<=> 1 is ~L */
	{
	  sp = exp;
	  return Simplify(-1, le_word);
	}

      if (l == NOT)		/* ~X ~<=> R is X <=> R */
	{
	  exp[0] = EQUIV;
	  exp[1] += sizeof(WamWord);
	  break;
	}

      if (r == NOT)		/* L ~<=> ~X is L <=> X */
	{
	  exp[0] = EQUIV;
	  exp[2] += sizeof(WamWord);
	  break;
	}

      if (IsVar(l) && !IsVar(r)) /* X ~<=> R is X <=> ~R */
	{
	  exp[0] = EQUIV;
	  sp = sp1;
	  exp[2] = (WamWord) Simplify(-1, re_word);
	  break;
	}

      if (IsVar(r) && !IsVar(l)) /* L ~<=> X is L <=> ~X */
	{
	  exp[0] = EQUIV;	/* NB: cannot recover the stack */
	  exp[1] = (WamWord) Simplify(-1, le_word);
	  break;
	}
      break;

    case IMPLY:
      if (l == ZERO || r == ONE) /* 0 ==> R is 1 , L ==> 1 is 1 */
	{
	  sp = exp;
	  *sp++ = ONE;
	  break;
	}

      if (l == ONE)		/* 1 ==> R is R */
	{
	  return (WamWord *) exp[2];
	}

      if (r == ZERO)		/* L ==> 0 is ~L */
	return sp = exp, Simplify(-1, le_word);

      if (l == NOT)		/* ~X ==> R is X \/ R */
	{
	  exp[0] = OR;
	  exp[1] += sizeof(WamWord);
	  break;
	}

      if (r == NOT)		/* L ==> ~X is X ==> ~L */
	{
	  exp[1] = exp[2] + sizeof(WamWord);
	  exp[2] = (WamWord) Simplify(-1, le_word);
	  break;
	}
      break;

    case NIMPLY:
      if (l == ZERO || r == ONE) /* 0 ~==> R is 0 , L ~==> 1 is 0 */
	{
	  sp = exp;
	  *sp++ = ZERO;
	  break;
	}

      if (l == ONE)		/* 1 ~==> R is ~R */
	{
	  sp = exp;
	  return Simplify(-1, re_word);
	}

      if (r == ZERO)		/* L ~==> 0 is L */
	{
	  sp = sp1;
	  return (WamWord *) exp[1];
	}

      if (l == NOT)		/* ~X ~==> R is X ~\/ R */
	{
	  exp[0] = NOR;
	  exp[1] += sizeof(WamWord);
	  break;
	}

      if (r == NOT)		/* L ~==> ~X is L /\ X */
	{
	  exp[0] = AND;
	  exp[2] += sizeof(WamWord);
	  break;
	}
      break;

    case AND:
      if (l == ZERO || r == ZERO) /* 0 /\ R is 0 , L /\ 0 is 0 */
	{
	  sp = exp;
	  *sp++ = ZERO;
	  break;
	}

      if (l == ONE)		/* 1 /\ R is R */
	{
	  return (WamWord *) exp[2];
	}

      if (r == ONE)		/* L /\ 1 is L */
	{
	  sp = sp1;
	  return (WamWord *) exp[1];
	}

      if (l == NOT)		/* ~X /\ R is R ~==> X */
	{
	  exp[0] = NIMPLY;
	  word = exp[1];
	  exp[1] = exp[2];
	  exp[2] = word + sizeof(WamWord);
	  break;
	}

      if (r == NOT)		/* L /\ ~X is L ~==> X */
	{
	  exp[0] = NIMPLY;
	  exp[2] += sizeof(WamWord);
	  break;
	}
      break;

    case NAND:
      if (l == ZERO || r == ZERO) /* 0 ~/\ R is 1 , L ~/\ 0 is 1 */
	{
	  sp = exp;
	  *sp++ = ONE;
	  break;
	}

      if (l == ONE)		/* 1 ~/\ R is ~R */
	{
	  sp = exp;
	  return Simplify(-1, re_word);
	}

      if (r == ONE)		/* L ~/\ 1 is ~L */
	{
	  sp = exp;
	  return Simplify(-1, le_word);
	}

      if (l == NOT)		/* ~X ~/\ R is R ==> X */
	{
	  exp[0] = IMPLY;
	  word = exp[1];
	  exp[1] = exp[2];
	  exp[2] = word + sizeof(WamWord);
	  break;
	}

      if (r == NOT)		/* L ~/\ ~X is L ==> X */
	{
	  exp[0] = IMPLY;
	  exp[2] += sizeof(WamWord);
	  break;
	}
      break;

    case OR:
      if (l == ONE || r == ONE)	/* 1 \/ R is 1 , L \/ 1 is 1 */
	{
	  sp = exp;
	  *sp++ = ONE;
	  break;
	}

      if (l == ZERO)		/* 0 \/ R is R */
	{
	  return (WamWord *) exp[2];
	}

      if (r == ZERO)		/* L \/ 0 is L */
	{
	  sp = sp1;
	  return (WamWord *) exp[1];
	}

      if (l == NOT)		/* ~X \/ R is X ==> R */
	{
	  exp[0] = IMPLY;
	  exp[1] += sizeof(WamWord);
	  break;
	}

      if (r == NOT)		/* L \/ ~X is X ==> L */
	{
	  exp[0] = IMPLY;
	  word = exp[1];
	  exp[1] = exp[2] + sizeof(WamWord);
	  exp[2] = word;
	  break;
	}
      break;

    case NOR:
      if (l == ONE || r == ONE)	/* 1 ~\/ R is 0 , L ~\/ 1 is 0 */
	{
	  sp = exp;
	  *sp++ = ZERO;
	  break;
	}

      if (l == ZERO)		/* 0 ~\/ R is ~R */
	{
	  sp = exp;
	  return Simplify(-1, re_word);
	}

      if (r == ZERO)		/* L ~\/ 0 is ~L */
	{
	  sp = exp;
	  return Simplify(-1, le_word);
	}

      if (l == NOT)		/* ~X ~\/ R is X ~==> R */
	{
	  exp[0] = NIMPLY;
	  exp[1] += sizeof(WamWord);
	  break;
	}

      if (r == NOT)		/* L ~\/ ~X is X ~==> L */
	{
	  exp[0] = NIMPLY;
	  word = exp[1];
	  exp[1] = exp[2] + sizeof(WamWord);
	  exp[2] = word;
	  break;
	}
      break;
    }

  return exp;
}
Exemple #4
0
static CVOID__PROTO(shuntVariables) {
    tagged_t *pt = w->trail_top;
    node_t *cp = Gc_Aux_Node;
    node_t *prevcp = w->node;
    try_node_t *alt = fail_alt;
    intmach_t i;
    tagged_t *limit;
    frame_t *frame;

    while (ChoiceYounger(cp,Gc_Choice_Start)) {
      limit = TagToPointer(prevcp->trail_top);
      while (TrailYounger(pt,limit)) {
        tagged_t v = TrailPop(pt);

        if (v!=0 && IsVar(v) && !gc_IsMarked(*TagToPointer(v)))
          gc_MarkM(*TagToPointer(v));
        else
          gc_MarkM(pt[0]);
      }
      gc_ReverseChoice(cp,prevcp,alt);
    }

    while (ChoiceYounger(Gc_Aux_Node,cp)) {
      gc_UndoChoice(cp,prevcp,alt);
      limit = TagToPointer(cp->trail_top);
      pt = TagToPointer(prevcp->trail_top);
      while (TrailYounger(limit,pt)) {
        tagged_t v = *pt++;

        if (!gc_IsMarked(v))
          gc_UnmarkM(*TagToPointer(v));
      }
      pt = TagToPointer(prevcp->trail_top);
      while (TrailYounger(limit,pt)) {
        tagged_t v = *pt++;

        if (gc_IsMarked(v))
          gc_UnmarkM(pt[-1]);
        else
          gc_shuntVariable(*TagToPointer(v));
      }
      pt = NodeGlobalTop(prevcp);
      while (HeapYounger(NodeGlobalTop(cp),pt)) {
        tagged_t v = *pt++;

        if (v&QMask) pt += LargeArity(v);
        else if (!gc_IsMarked(v)) {
          if (v==Tag(CVA,pt-1))
            gc_MarkM(Cvas_Found),
              pt[-1] = Cvas_Found,
              Cvas_Found = v,
              pt += 2;
          else {
            gc_shuntVariable(pt[-1]);
          }
        }
      }
      i = FrameSize(cp->next_insn);
      frame = cp->frame;
      while (OffStacktop(frame,NodeLocalTop(prevcp))) {
        pt = (tagged_t *)StackCharOffset(frame,i);
        while (pt!=frame->term)
          if (!gc_IsMarked(*(--pt)))
            gc_shuntVariable(*pt);
        i = FrameSize(frame->next_insn);
        frame = frame->frame;
      }
	
      pt = cp->term+OffsetToArity(alt->node_offset);
      while (pt!=cp->term) {
        --pt;
        gc_shuntVariable(*pt);
      }
    }
}