Пример #1
0
int reachStatus(NFA nfa, int status_index, wchar_t c)
{
    int i, e_index;
    assert(nfa);
    assert(status_index>=0 && status_index<Array_length(nfa->statusArray));
    
    Status  currStatus;
    Array_T outEdges;
    Edge    e;

    currStatus = Array_get(nfa->statusArray, status_index);
    outEdges = getOutEdges(currStatus);
    if (!outEdges)
        return -1;

    for (i=0; i<Array_length(outEdges); i++)
    {
        e_index = *(int*)Array_get(outEdges, i);
        e = Array_get(nfa->edgeArray, e_index);
        if (crossEdge(e, c))
        {
            return getStatusID(gettoStatus(e));
        }
    }
    return -1;
}
Пример #2
0
/*
C implementation of stream::Object::intern_poll

Imported methods signatures:
	bigint Array_length( Array recv ) for array::AbstractArrayRead::(abstract_collection::Collection::length)
	nullable_Object Array__index( Array recv, bigint index ) for array::Array::(abstract_collection::SequenceRead::[])
	int nullable_Object_is_a_bigint( nullable_Object value ) to check if a nullable Object is a Int
	bigint nullable_Object_as_bigint( nullable_Object value ) to cast from nullable Object to Int
	int Int_is_null( nullable_Int value ) to check if a nullable Int is a Int
	bigint bigint_as_not_null( nullable_Int value ) to cast from nullable Int to Int
*/
nullable_Int Object_intern_poll___impl( Object recv, Array in_fds, Array out_fds ) {
	int in_len, out_len, total_len;
	struct pollfd *c_fds;
	sigset_t sigmask;
	int i;
	nullable_Object tmp_nit_obj;
	int first_polled_fd = -1;
	int result;

	in_len = Array_length( in_fds );
	out_len = Array_length( out_fds );
	total_len = in_len + out_len;
	c_fds = malloc( sizeof(struct pollfd) * total_len );

	/* input streams */
	for ( i=0; i<in_len; i ++ ) {
		int fd;
		tmp_nit_obj = Array__index( in_fds, i );
		fd = nullable_Object_as_Int( tmp_nit_obj );

		c_fds[i].fd = fd;
		c_fds[i].events = POLLIN;
	}

	/* output streams */
	for ( i=0; i<out_len; i ++ ) {
		int fd;
		tmp_nit_obj = Array__index( out_fds, i );
		fd = nullable_Object_as_Int( tmp_nit_obj );

		c_fds[i].fd = fd;
		c_fds[i].events = POLLOUT;
	}

	/* poll all fds, unlimited timeout */
	result = poll( c_fds, total_len, -1 );

	if ( result > 0 ) {
		/* analyse results */
		for ( i=0; i<total_len; i++ )
			if ( c_fds[i].revents & c_fds[i].events || /* awaited event */
				 c_fds[i].revents & POLLHUP ) /* closed */
			{
				first_polled_fd = c_fds[i].fd;
				break;
			}

		return Int_as_nullable( first_polled_fd );
	}
	else if ( result < 0 )
		fprintf( stderr, "Error in Stream:poll: %s\n", strerror( errno ) );

	return null_Int();
}
Пример #3
0
NFA Union (NFA nfa1, NFA nfa2 )
{
    int i, j, n1, n2, n, e1, e2;
    NFA     combined_NFA;
    Status  s;

    Edge    e;

    /* 得到两个NFA 边(Edge)数 和 顶点(Status)数 */
    n1 = Array_length (nfa1->statusArray);
    n2 = Array_length (nfa2->statusArray);
    e1 = Array_length (nfa1->edgeArray);
    e2 = Array_length (nfa2->edgeArray);

    n = n1 + n2 + 2;

    combined_NFA = malloc (sizeof (struct Automaton));
    assert(combined_NFA);

    combined_NFA->statusArray = allocStatusArray(n);


    /* 构造边集合, 即两个NFA的边数加上4条ε边 */
    n = e1 + e2 + 4;
    combined_NFA->edgeArray = allocEdgeArray(n); 

    /* 提取0号边 */
    e = Array_get (combined_NFA->edgeArray, 0);
    setEpsilon (e);
    link_Two_Status_In_Automaton (combined_NFA, 0, 1, 0);
    
    adjustStatusEdges (combined_NFA, nfa1, 1, 2);
     
    e = Array_get (combined_NFA->edgeArray, 1);
    setEpsilon (e);
    link_Two_Status_In_Automaton (combined_NFA, 0, n1+1, 1);

    adjustStatusEdges (combined_NFA, nfa2, n1+1, e1+2);

    setEpsilon (Array_get (combined_NFA->edgeArray, e1+e2+2));
    link_Two_Status_In_Automaton (combined_NFA, n1, n1+n2+1, e1+e2+2);

    setEpsilon (Array_get (combined_NFA->edgeArray, e1+e2+3));
    link_Two_Status_In_Automaton (combined_NFA, n1+n2, n1+n2+1, e1+e2+3);

    adjustStatusID (combined_NFA);
    ensureFinalStatus (combined_NFA->end);

    free_Automaton(nfa1);
    free_Automaton(nfa2);

    return combined_NFA ;
}
Пример #4
0
CAMLprim value ml_gsl_ran_sample(value rng, value src, value dest)
{
  if(Tag_val(src) == Double_array_tag)
    gsl_ran_sample(Rng_val(rng), 
		   Double_array_val(dest), Double_array_length(dest),
		   Double_array_val(src), Double_array_length(src),
		   sizeof(double));
  else
    gsl_ran_sample(Rng_val(rng), 
		   (value *)dest, Array_length(dest),
		   (value *)src,  Array_length(src),
		   sizeof(value));
  return Val_unit;
}
Пример #5
0
NFA CopyNFA (NFA nfa)
{
    int i, id, n;
    NFA     copyNFA ;
    Status  fromS, toS, s1, s2;
    Edge    e, e_temp;

    copyNFA = malloc (sizeof (NFA));
    assert (copyNFA);

    /* 首先,复制nfa状态数组中所有状态 */
    n = Array_length (nfa->statusArray);
    copyNFA -> statusArray = Array_new (n, sizeOfStatus());
    Array_copy_from_range (copyNFA->statusArray, 0, nfa->statusArray, 0, n);

    /* 第二步,复制所有边(除了指向前后Status的储存单元 */
    n = Array_length (nfa->edgeArray);
    copyNFA -> edgeArray = Array_new (n, sizeOfEdge());
    Array_copy_from_range (copyNFA->edgeArray, 0, nfa->edgeArray, 0, n);

    /* 第三部,针对edgeArray的每一条边,生成每个Status的InEdges和OutEdges */
    for (i=0; i < Array_length (nfa->edgeArray); i++)
    {
        e = (Edge)Array_get (nfa->edgeArray, i);
        fromS   = getfromStatus (e);
        toS     = gettoStatus (e);

        e = Array_get (copyNFA->edgeArray, i);
        
        id = getStatusID (fromS);
        s1 = Array_get (copyNFA->statusArray, id);
        appendOutEdge (s1, i);
        
        id = getStatusID (toS);
        s2 = Array_get (copyNFA->statusArray, id);
        appendInEdge (s2, i);
        
        setFromToStatus (e, s1, s2);
    }

    /* 最后,更新start 和 end */
    n = Array_length (copyNFA->statusArray);
    copyNFA -> start = Array_get (copyNFA->statusArray, 0); 
    copyNFA -> end   = Array_get (copyNFA->statusArray, n-1); 
    ensureFinalStatus (copyNFA->end);
    
    return copyNFA;
}
Пример #6
0
void get_two_StatusSet_Table (NFA nfa, StatusSet_table *T, int inverse[])
{
    int     i, j, id, n, curr_set_id, e_index;
    Edge    e;
    Status  s;
    Array_T StatusArray, edgeArray, OutEdges, closure;
 

    T->size = 0;
    StatusArray = getStatusArray (nfa);
    edgeArray   = getEdgeArray (nfa);
    n = Array_length (StatusArray);
 
    /* 一开始所有状态不属于任一集合 */
    for (i=0; i<n; i++) inverse[i] = -1;

    for (i=0; i<n; i++)
    {
        if (inverse[i] != -1)
            continue;
        /* 闭包缓存 */
        curr_set_id = T->size;

        inverse[i] = curr_set_id;

        closure = Array_new (0, sizeof(int));
        s = Array_get(StatusArray, i);

        getEpsilonClosure(s, nfa, closure, inverse, curr_set_id);
        for (j=0; j<Array_length(closure); j++)
        {
            id = *(int*)Array_get(closure, j);
            s = Array_get(nfa->statusArray, id);
            if (isFinalStatus(s))
              T->H[T->size].hasFinalStatus = true;
        }

        /* 以s为原点进行DFS,找出所有epsilon闭包 
         * getEpsilonClosure(s, closure, inverse)
         */
        T->H[T->size].epsClosure = closure;
        //printStatusSet(T->H[T->size]);
        //wprintf(L"-------------------------------\n");

        T->size++;
    }

}
Пример #7
0
// 根据nfa中图结构,为copyNFA构建一样的图结构,其中
// copyNFA中的顶点下标从s_offset开始计数,边下标从e_offset开始计数
static void adjustStatusEdges (NFA copyNFA, NFA nfa, int s_offset, int e_offset)
{
    int i, id, id2;
    Edge e, e_temp;
    Status s1, s2, fromS, toS;
    for (i=0; i < Array_length (nfa->edgeArray); i++)
    {
        e_temp  = Array_get (nfa->edgeArray, i);
        e = Array_get (copyNFA->edgeArray, i+e_offset);
        copyEdge_without_Status (e, e_temp);
        
        id = getStatusID (getfromStatus (e_temp));
        s1 = Array_get (copyNFA->statusArray, id+s_offset);

        id2 = getStatusID (gettoStatus (e_temp));
        s2 = Array_get (copyNFA->statusArray, id2+s_offset);
        if (id==id2)
        {
            wprintf(L"error!!!\n");
        }

        link_Two_Status_In_Automaton (copyNFA, id+s_offset, id2+s_offset, i+e_offset);
        //linkTwoStatus_by_AnEdge (s1, s2, e);
    }
}
Пример #8
0
static void node_response(ServicesData servicesData, struct Node *from, struct RequestData *request) {
	uint8_t *ptr = request->buffer;

	int type  = GetFromBuffer8(&ptr);

	if (type == NODESERVICE_TYPE_TAKE) {

		size_t count = GetFromBuffer32(&ptr);
		if (request->len - 1 < count * ITEM_SIZE) {
			DWARNING("NODE SERVICE: node length is insufficient = %i\n", request->len - 1);
			return;
		}


		Array array = Array_init(0, sizeof(uint32_t));
		for (size_t i = 0; i < count; i++) {
			uint32_t ip4addr = GetFromBuffer32NoOrder(&ptr);
			struct Node *client = nodes_get_node(ip4addr);
			if (!balancing_is_in_session(servicesData->balancer, ip4addr) && client && client->owned_by && nodes_is_me(client->owned_by)) {
				balancing_release_node(servicesData->balancer, client->ip4addr);
				Array_add(array, &ip4addr);
			}
		}

		if (Array_length(array) > 0) {
			NodeRequest request = {
					.type = NODESERVICE_TYPE_GIVE,
					.ip4array = array
			};
			Services_Request(servicesData, NodeService_Get(), from, &request);
		}
Пример #9
0
static void DFS(Status fromS, NFA nfa, Array_T closure, int inverse[], int color[], int set)
{
    int     i, index, from, to;
    Edge    e;
    Status  toS;

    from = getStatusID(fromS);
    color[from] = 1;
    inverse[from] = set;
    Array_append(closure, &from);
    
    Array_T edgeArray   =   getEdgeArray(nfa);
    Array_T outEdges_indice = getOutEdges(fromS);
    if (!outEdges_indice)
        return;

    for (i=0; i<Array_length(outEdges_indice); i++)
    {
        index   =   *(int*)Array_get(outEdges_indice, i);  
        e       =   (Edge)Array_get(edgeArray, index);
        if (isEpsilon(e))
        {
            toS     =   gettoStatus(e);
            to      =   getStatusID(toS);
            if (color[to] == 0)
                DFS(toS, nfa, closure, inverse, color, set);
        }
    }
}
Пример #10
0
void printStatusSet(StatusSet S)
{
    int i;
    wprintf(L"eps_Closure: ");
    for (i=0; i<Array_length(S.epsClosure); i++)
        wprintf(L"%d ", *(int*)Array_get(S.epsClosure, i));
    wprintf(L"\n");
}
Пример #11
0
NFA Link (NFA frontNFA, NFA toNFA )
{
    int i, j, numStatus ;
    int n1, n2, n;
    NFA combined_NFA;
    Edge bridge;
    Status s, s1, s2;

    
    combined_NFA = malloc (sizeof (struct Automaton));
    assert(combined_NFA);

    /* 构造combined_NFA所有状态 */
    n = Array_length (frontNFA->statusArray) + Array_length (toNFA->statusArray);
    
    combined_NFA->statusArray = allocStatusArray(n);
    
    adjustStatusID (combined_NFA);
    combined_NFA->start = Array_get(combined_NFA->statusArray, 0);
    combined_NFA->end = Array_get(combined_NFA->statusArray, n-1);
    ensureFinalStatus(combined_NFA->end);
    
    /* combined_NFA边集合 <=> 两个nfa以及连接它们的边ε*/
    n = Array_length(frontNFA->edgeArray) + Array_length(toNFA->edgeArray) + 1;
    
    combined_NFA->edgeArray = allocEdgeArray(n);
    
    adjustStatusEdges(combined_NFA, frontNFA, 0, 0);
    
    n1 = Array_length (frontNFA->statusArray);
    n2 = Array_length (toNFA->statusArray);
    /* 连结两个NFA图的边是epsilon edge */
    bridge = Array_get(combined_NFA->edgeArray, Array_length(frontNFA->edgeArray)); 
    setEpsilon (bridge);
    // 提取对应于frontNFA状态的最后一个状态
    s1 = Array_get (combined_NFA->statusArray, n1-1);
    s2 = Array_get (combined_NFA->statusArray, n1);
    link_Two_Status_In_Automaton (combined_NFA, n1-1, n1, Array_length(frontNFA->edgeArray));
    // linkTwoStatus_by_AnEdge (s1, s2, bridge);
     

    /* 根据已有的NFA, 确认combined_NFA中边和点之间的关系 */
    /* 已边数: frontNFA所有边以及bridge, 所以边计数从n开始*/
    n = Array_length (frontNFA->edgeArray) + 1;
    adjustStatusEdges (combined_NFA, toNFA, n1, n);

    free_Automaton(frontNFA);
    free_Automaton(toNFA);

    return combined_NFA ;
}
Пример #12
0
/* SHUFFLING */
CAMLprim value ml_gsl_ran_shuffle(value rng, value arr)
{
  if(Tag_val(arr) == Double_array_tag)
    gsl_ran_shuffle(Rng_val(rng), Double_array_val(arr),
		    Double_array_length(arr), sizeof(double));
  else
    gsl_ran_shuffle(Rng_val(rng), (value *)arr, 
		    Array_length(arr), sizeof(value));
  return Val_unit;
}
Пример #13
0
/*
 *  nfa1 G: n×e
 *  以下是 求nfa闭包
 *
                       e+2 号边
                 —————————————————————
                |                   |
                |                   |       
 *  (0号边)      —>    ------   —————— 
 *    ————————————>  |  nfa  | —————————————————
      |                ------        e+3号边    |
      |                                         v
    -----                                     -----
  | start | (0号顶点)                        | end | (n+1) 号顶点
    -----                                     -----
    |                                         |
     ———————————————————————————————————————————
                       1号边
    
    边顺序:     0号 
                1号  
                nfa中的e条边:    2, 3, ...  e
                e+2号边
                (e+3)号边

    顶点顺序:   start:  0号,  
                nfa中n个顶点:     1, 2, 3, ..., n
                end :   n+1


 */
NFA Closure(NFA nfa)
{
    NFA     newnfa;

    int n, e;

    newnfa = malloc (sizeof (struct Automaton));
    assert (newnfa);

    /* 构造边数组 */
    e = Array_length (nfa->edgeArray);
    newnfa->edgeArray = allocEdgeArray (e+4);
  
    // 得到nfa状态个数
    n = Array_length (nfa->statusArray);
    newnfa->statusArray = allocStatusArray (n+2);

    /* 提取0号边 */
    setEpsilon (Array_get (newnfa->edgeArray, 0));
    link_Two_Status_In_Automaton (newnfa, 0, 1, 0);

    /* 提取1号边 */
    setEpsilon (Array_get (newnfa->edgeArray, 1));
    link_Two_Status_In_Automaton (newnfa, 0, n+1, 1);

    /* 在newnfa中构造与nfa对应一样的图结构 */
    adjustStatusEdges (newnfa, nfa, 1, 2);

    /* 提取e+2号边 */
    setEpsilon (Array_get (newnfa->edgeArray, e+2));
    link_Two_Status_In_Automaton (newnfa, n, 1, e+2);

    /* 提取e+3号边 */
    setEpsilon (Array_get (newnfa->edgeArray, e+3));
    link_Two_Status_In_Automaton (newnfa, n, n+1, e+3);
    
    adjustStatusID (newnfa); 

    free_Automaton(nfa);
    
    return newnfa;
}
Пример #14
0
DFATable
makeUpDFATable (DFA dfa)
{
    int i, j, n;
    Edge    e;
    /* 针对DFA的每条边e, 其上的非匹配字符 记录在此数组中 */
    bool    isInMatchChar[128];
    wchar_t c;
    Range   range;
    int     fromID, toID;

    DFATable    T;
    n   =   Array_length(dfa->statusArray);
    T   =  malloc (sizeof(int*) * n);
    assert(T);

    for( i=0; i < n; i++ )
    {
        T[i] = malloc (sizeof(int) * 128);
        assert(T[i]);
        for (j=0; j<128; j++)  T[i][j] = -1;
    }

    for (i=0; i < Array_length(dfa->edgeArray); i++)
    {
        e = Array_get(dfa->edgeArray, i);
        fromID  =   getStatusID(getfromStatus(e));
        toID    =   getStatusID(gettoStatus(e));

        Array_T content = getEdgeContent(e);
        for (j=0; j<Array_length(content); j++)
        {
            c = *(wchar_t*)Array_get(content, j);
            T[fromID][c] = toID;
        }
    }

    return T; 
}
Пример #15
0
Array_T reach_Status (NFA nfa, StatusSet currSet, int inverse[], wchar_t c)
{
    Array_T toSets;
    int  from, to;

    toSets = Array_new(0,sizeof(int));

    int i;

    for (i=0; i<Array_length(currSet.epsClosure); i++)
    {
        from = *(int*)Array_get(currSet.epsClosure, i);
        to = reachStatus(nfa, from, c);
        if (to!=-1)
        {
            Array_append(toSets, &inverse[to]);
        }
    }

    return toSets;
}
Пример #16
0
Array_T 
getCharSet(NFA nfa)
{
    int     i;
    ULL128  v;
    ULL64   a = 1ULL;
    Edge    e;
    wchar_t c;

    Array_T charSet;
    charSet = Array_new(0,sizeof(wchar_t));

    setZero(&v);

    for (i=0; i<Array_length(nfa->edgeArray); i++)
    {
        e = Array_get(nfa->edgeArray, i);
        if (!isEpsilon(e))
        {
            v = Or(getMatchBitVector(e), v);
        }
    }
    for (i=0; i<64; i++)
    {
        c = (wchar_t)i;
        if ((a & v.L64) != 0)
            Array_append (charSet, &c);
        a <<= 1;
    }
    a = 1ULL;
    for (i=0; i<64; i++)
    {
        c = (wchar_t)(i+64);
        if ((a & v.H64) != 0)
            Array_append (charSet, &c);
        a <<= 1;
    }
    return charSet;
}
Пример #17
0
static struct RequestData send_nodes(uint8_t type, Array ip4array) {
	assert(ip4array);
	assert(Array_checkType(ip4array, sizeof(uint32_t)));

	size_t count = Array_length(ip4array);
	if (count == 0) {
		struct RequestData result = {0, NULL};
		return result;
	}

	int len = count * (ITEM_SIZE) + 5;
	uint8_t *buffer = malloc(len);
	uint8_t *ptr = buffer;

	AddToBuffer8(&ptr, type);
	AddToBuffer32(&ptr, count);
	for (int i = 0; i < count; i++) {
		AddToBuffer32NoOrder(&ptr, ARRAY_GET(ip4array, uint32_t, i));
	}

	struct RequestData result = {len, buffer};
	return result;
}
Пример #18
0
void Player_beginner2_think(Player* player, Othello* othello, int* x, int* y, BOOL* isResign){
    // 最もたくさんの数が取れる場所に打つ
    Evaluation eval;
    PointList list;

    Othello_moveList(othello, &list);

    if(list.length > 0){
        eval = Player_beginner2_search(player, othello, &list, 5);

        *x = list.x[eval.index];
        *y = list.y[eval.index];
        *isResign = FALSE;
    }
    else{
        *isResign = TRUE;
    }

    {
        Array int_array;
        int temp;
        int temp_out;
        int i;
        Array_new(&int_array, 5, sizeof(int));
        temp = 0; Array_append(&int_array, &temp);
        temp = 1; Array_append(&int_array, &temp);
        temp = 2; Array_append(&int_array, &temp);
        temp = 3; Array_append(&int_array, &temp);
        temp = 4; Array_append(&int_array, &temp);
        temp = 5; Array_append(&int_array, &temp);

        for(i = 0; i < Array_length(&int_array); i++){
            temp_out = *(int*)Array_get(&int_array, i);
        }
        Array_delete(&int_array);
    }
}
Пример #19
0
int NLEnergy_parse_eval(NLEnergy *p, Tcl_Interp *interp,
    int objc, Tcl_Obj *const objv[], int evalType) {
  enum { KEYWD, ATOM, BOND, ANGLE, DIHED, IMPR, ELEC, VDW, NONB };
  const Topology *topo = &(p->topo);
  const int32 natoms = Topology_atom_array_length(topo);
  const int32 nbonds = Topology_bond_array_length(topo);
  const int32 nangles = Topology_angle_array_length(topo);
  const int32 ndiheds = Topology_dihed_array_length(topo);
  const int32 nimprs = Topology_impr_array_length(topo);
  int32 ninvs;
  char *atomsel, *nonbsel, *bondsel, *anglesel, *dihedsel, *imprsel, *invsel;
  int32 i;
  int state = KEYWD, s;
  int setnum = 0, mark = FALSE;
  boolean invert = FALSE;

  TEXT("eval");
  if (Array_length(&(p->atomsel)) != natoms
      && (s=Array_resize(&(p->atomsel), natoms)) != OK) return ERROR(s);
  atomsel = Array_data(&(p->atomsel));
  if (Array_length(&(p->nonbsel)) != natoms
      && (s=Array_resize(&(p->nonbsel), natoms)) != OK) return ERROR(s);
  nonbsel = Array_data(&(p->nonbsel));
  if (Array_length(&(p->bondsel)) != nbonds
      && (s=Array_resize(&(p->bondsel), nbonds)) != OK) return ERROR(s);
  bondsel = Array_data(&(p->bondsel));
  if (Array_length(&(p->anglesel)) != nangles
      && (s=Array_resize(&(p->anglesel), nangles)) != OK) return ERROR(s);
  anglesel = Array_data(&(p->anglesel));
  if (Array_length(&(p->dihedsel)) != ndiheds
      && (s=Array_resize(&(p->dihedsel), ndiheds)) != OK) return ERROR(s);
  dihedsel = Array_data(&(p->dihedsel));
  if (Array_length(&(p->imprsel)) != nimprs
      && (s=Array_resize(&(p->imprsel), nimprs)) != OK) return ERROR(s);
  imprsel = Array_data(&(p->imprsel));

  /* find max length for inverse selection array */
  ninvs = natoms;
  if (ninvs < nbonds)  ninvs = nbonds;
  if (ninvs < nangles) ninvs = nangles;
  if (ninvs < ndiheds) ninvs = ndiheds;
  if (ninvs < nimprs)  ninvs = nimprs;
  if (Array_length(&(p->invsel)) != ninvs
      && (s=Array_resize(&(p->invsel), ninvs)) != OK) return ERROR(s);
  invsel = Array_data(&(p->invsel));

  if (0 == objc) {
    memset(atomsel, 0, natoms);
    memset(nonbsel, ASEL_NONB, natoms);
    memset(bondsel, TRUE, nbonds);
    memset(anglesel, TRUE, nangles);
    memset(dihedsel, TRUE, ndiheds);
    memset(imprsel, TRUE, nimprs);
  }
  else {
    const char *t = NULL;
    state = KEYWD;
    memset(atomsel, 0, natoms);
    memset(nonbsel, 0, natoms);
    memset(bondsel, 0, nbonds);
    memset(anglesel, 0, nangles);
    memset(dihedsel, 0, ndiheds);
    memset(imprsel, 0, nimprs);
    i = 0;
    INT(objc);
    while (i <= objc) {
      INT(i);
      switch (state) {
        case KEYWD:
          if (i == objc) { i++; break; }
          t = Tcl_GetString(objv[i]);
          setnum = 0;
          invert = FALSE;
          if ('-'==t[0]) { invert = TRUE;  t++; }
          else if ('+'==t[0])  { t++; }
          if (strcmp(t,"atom")==0)       state = ATOM;
          else if (strcmp(t,"bond")==0)  state = BOND;
          else if (strcmp(t,"angle")==0) state = ANGLE;
          else if (strcmp(t,"dihed")==0) state = DIHED;
          else if (strcmp(t,"impr")==0)  state = IMPR;
          else if (strcmp(t,"elec")==0)  state = ELEC;
          else if (strcmp(t,"vdw")==0)   state = VDW;
          else if (strcmp(t,"nonb")==0)  state = NONB;
          else return ERROR(ERR_EXPECT);
          i++;
          break;
        case BOND:
          s = FAIL;
          if (i<objc && (s=parse_bondlist(p,interp,objv[i],invert))==OK) i++;
          //else if (s < FAIL) return ERROR(s);
          else if ( ! invert ) memset(bondsel, TRUE, nbonds);
          state = KEYWD;
          break;
        case ANGLE:
          s = FAIL;
          if (i<objc && (s=parse_anglelist(p,interp,objv[i],invert))==OK) i++;
          //else if (s < FAIL) return ERROR(s);
          else if ( ! invert ) memset(anglesel, TRUE, nangles);
          state = KEYWD;
          break;
        case DIHED:
          s = FAIL;
          if (i<objc && (s=parse_dihedlist(p,interp,objv[i],invert))==OK) i++;
          //else if (s < FAIL) return ERROR(s);
          else if ( ! invert ) memset(dihedsel, TRUE, ndiheds);
          state = KEYWD;
          break;
        case IMPR:
          s = FAIL;
          if (i<objc && (s=parse_imprlist(p,interp,objv[i],invert))==OK) i++;
          //else if (s < FAIL) return ERROR(s);
          else if ( ! invert ) memset(imprsel, TRUE, nimprs);
          state = KEYWD;
          break;
        default:  /* ATOM, ELEC, VDW, or NONB */
          if (i==objc && setnum > 0) { state = KEYWD; continue; }
          if (ATOM==state) mark = (0==setnum ? -ASEL_NONB : -ASEL_NONB_B);
          else if (ELEC==state) mark = (0==setnum ? ASEL_ELEC : ASEL_ELEC_B);
          else if (VDW==state)  mark = (0==setnum ? ASEL_VDW  : ASEL_VDW_B);
          else                  mark = (0==setnum ? ASEL_NONB : ASEL_NONB_B);
          INT(ASEL_NONB==mark);
          INT(ASEL_NONB_B==mark);
          s = FAIL;
          if (i<objc && (s=parse_atomlist(p,interp,objv[i],invert,mark))==OK) {
            i++;
            setnum++;
            if (invert || 2==setnum) state = KEYWD;
          }
#if 0
          else if (s < FAIL) {
            if (setnum > 0) continue;
            else return ERROR(s);
          }
#endif
          else if (0==setnum &&  !invert) {
            if (mark > 0) {
              memset(nonbsel, mark, natoms);
            }
            else {
              memset(atomsel, -mark, natoms);
            }
            state = KEYWD;
          }
          else state = KEYWD;
      } /* switch */
    } /* while */
  } /* else */

  if ((s=select_from_atomlist(p)) != OK) return ERROR(s);

  /* evaluation */
  if (EVAL_ENERGY==evalType || EVAL_FORCE==evalType) {
    if ((s=NLEnergy_eval_force(p)) != OK) return ERROR(s);
  }
  else {
    /* minimize not yet supported */
    return ERROR(ERR_EXPECT);
  }

  /* output */
  if (EVAL_ENERGY==evalType) {
    Tcl_Obj *a = NULL;
    if ((s=NLEnergy_new_obj_dreal(interp, &a,
            p->ener.pe * ENERGY_EXTERNAL)) != OK) {
      return ERROR(s);
    }
    if ((s=NLEnergy_set_obj_result(interp, a)) != OK) return ERROR(s);
  }
  else if (EVAL_FORCE==evalType || EVAL_MINIMIZE==evalType) {
    const dvec *f = Coord_force_const(&(p->coord));
    Tcl_Obj *r = NULL;  /* return list of lists */
    Tcl_Obj *a = NULL;  /* list of atom index */
    Tcl_Obj *b = NULL;  /* list of force or potentials (MINIMIZE) */
    if ((s=atomlist_contrib(p)) != OK) return ERROR(s);
    if ((s=new_list(interp, &r)) != OK) return ERROR(s);
    if ((s=new_list(interp, &a)) != OK) return ERROR(s);
    if ((s=new_list(interp, &b)) != OK) return ERROR(s);
    for (i = 0;  i < natoms;  i++) {
      if (atomsel[i]) {
        if ((s=list_append_atomid(p,interp,a,i)) != OK) return ERROR(s);
        if (EVAL_FORCE==evalType) {
          dvec fs;
          VECMUL(fs, ENERGY_EXTERNAL, f[i]);
          if ((s=list_append_dvec(interp,b,&fs)) != OK) return ERROR(s);
        }
      }
    }
    if (EVAL_MINIMIZE==evalType) {
      return ERROR(ERR_EXPECT);
    }
    if ((s=list_append_obj(interp, r, a)) != OK) return ERROR(s);
    if ((s=list_append_obj(interp, r, b)) != OK) return ERROR(s);
    if ((s=set_obj_result(interp, r)) != OK) return ERROR(s);
  }
  else {
    /* nothing else is supported */
    return ERROR(ERR_EXPECT);
  }

#if 0
  if (objc >= 1) {
    const char *t = Tcl_GetString(objv[0]);
    if (strcmp(t,"bond")==0) {
      return NLEnergy_energy_bond(p, interp, objc-1, objv+1);
    }
    if (strcmp(t,"angle")==0) {
      return NLEnergy_energy_angle(p, interp, objc-1, objv+1);
    }
    if (strcmp(t,"dihed")==0) {
      return NLEnergy_energy_dihed(p, interp, objc-1, objv+1);
    }
    if (strcmp(t,"impr")==0) {
      return NLEnergy_energy_impr(p, interp, objc-1, objv+1);
    }
    if (strcmp(t,"elec")==0) {
      return NLEnergy_energy_nonbonded(p, FNBCUT_ELEC, interp, objc-1, objv+1);
    }
    if (strcmp(t,"vdw")==0) {
      return NLEnergy_energy_nonbonded(p, FNBCUT_VDW, interp, objc-1, objv+1);
    }
    if (strcmp(t,"nonbonded")==0) {
      return NLEnergy_energy_nonbonded(p, FNBCUT_ELEC | FNBCUT_VDW,
	  interp, objc-1, objv+1);
    }
  }
  return ERROR(ERR_EXPECT);
#endif

  return OK;
}