Example #1
0
File: elim.c Project: IEDMS/BNT-SM
void destroy_Elimination(Elimination elim){

  word w;
  Iterator iter;

  if(elim){
    destroy_Map(elim->ordering);
    if(elim->cliques){
      iter = get_Iterator(elim->cliques);
      while(!is_empty(iter)){
        w = next_value(iter);
        destroy_Map((Map) w.v);
      }
      destroy_Map(elim->cliques);
    }
    if(elim->fill_ins){
      if(elim->fill_ins[0]){
        free(elim->fill_ins[0]);
      }
      free(elim->fill_ins);
    }
    if(elim->node_map){
      iter = get_Iterator(elim->node_map);
      while(!is_empty(iter)){
        w = next_key(iter);
        if(w.v){
          destroy_Node((Node) w.v);
        }
      }
      destroy_Map(elim->node_map);
    }
    free(elim);
  }
}
Example #2
0
int find_exact(ENTRY *pe, IX_DESC *pix)
{
    int  ret;
    ENTRY e;
    copy_entry(&e, pe);
    ret = find_key(&e, pix);
    if ( ret && pci->duplicate)
    {
        do
        {
            ret = (e.recptr == pe->recptr);
            if(!ret)  
            {
                ret = next_key(&e, pci);
            }
            /*if (ret) ret = (strcmp(e.key, pe->key) == 0);*/
            if (ret) 
            {
                ret = (key_cmp(e.key, pe->key) == 0);
            }
            else
            {
                return 0;
            }

        } while(!ret);
    }

    copy_entry(pe, &e);

    return ret;
} 
size_t decode_dict(const char *b,size_t len,const char *keylist)
{
  size_t rl,dl,nl;
  const char *pkey;
  dl = 0;
  if(2 > len || *b != 'd') return 0;

  dl++; len--;
  for(;len && *(b + dl) != 'e';){
    rl = buf_str(b + dl,len,&pkey,&nl);

    if( !rl || KEYNAME_SIZ < nl) return 0;
    dl += rl;
    len -= rl;

    if(keylist && compare_key(pkey,nl,keylist) == 0){
      pkey = next_key(keylist);
      if(! *pkey ) return dl;
      rl = decode_dict(b + dl,len, pkey);
      if( !rl ) return 0;
      return dl + rl;
    }

    rl = decode_rev(b + dl,len,(const char*) 0);
    if( !rl ) return 0;

    dl += rl;len -= rl;
  }
  if( !len || keylist) return 0;
  return dl + 1;	/* add the last char 'e' */
}
Example #4
0
 bool const get_next_map_key(typename map_task_type::key_type *&key)
 {
     std::unique_ptr<typename map_task_type::key_type> next_key(new typename map_task_type::key_type);
     if (!datasource_.setup_key(*next_key))
         return false;
     key = next_key.release();
     return true;
 }
Example #5
0
File: elim.c Project: IEDMS/BNT-SM
void remove_node(Neighborhood * graph, int node){

  word w;
  word key;
  Iterator iter;

  key.i = node;
  iter = get_Iterator(graph[node]->parents);
  while(!is_empty(iter)){
    w = next_key(iter);
    rem(graph[w.i]->children, key);
  }
  iter = get_Iterator(graph[node]->children);
  while(!is_empty(iter)){
    w = next_key(iter);
    rem(graph[w.i]->parents, key);
  }
}
Example #6
0
File: mtree.c Project: taysom/tau
int next_mtree(struct iterator_mtree *imt)
{
	int rc;
	u64 blknum = find_root(imt->mt);

	if (!blknum)
		return DONE;
	rc = next_key(imt, blknum);
	return rc ? DONE : 0;
}
Example #7
0
void iterate(solution *sol, char *filename) {
    size_t num_states = num_keys(sol->d);

    int changed = 1;
    while (changed) {
        changed = 0;
        for (size_t j = 0; j < sol->num_layers; j++) {
            size_t key;
            size_t i;
            int tid;
            int num_threads;
            #pragma omp parallel private(i, key, tid, num_threads)
            {
                num_threads = omp_get_num_threads();
                state s_;
                state *s = &s_;
                tid = omp_get_thread_num();
                key = sol->d->min_key;
                for (i = 0; i < num_states; i++) {
                    if (i % num_threads == tid) {
                        assert(from_key_s(sol, s, key, j));
                        node_value new_v = negamax_node(sol, s, key, j, 1);
                        assert(new_v.low >= sol->base_nodes[j][i].low);
                        assert(new_v.high <= sol->base_nodes[j][i].high);
                        changed = changed || !equal(sol->base_nodes[j][i], new_v);
                        sol->base_nodes[j][i] = new_v;
                    }
                    key = next_key(sol->d, key);
                }
                #pragma omp for
                for (i = 0; i < sol->ko_ld->num_keys; i++) {
                    key = sol->ko_ld->keys[i];
                    assert(from_key_ko(sol, s, key, j));
                    node_value new_v = negamax_node(sol, s, key, j, 1);
                    assert(new_v.low >= sol->ko_nodes[j][i].low);
                    assert(new_v.high <= sol->ko_nodes[j][i].high);
                    changed = changed || !equal(sol->ko_nodes[j][i], new_v);
                    sol->ko_nodes[j][i] = new_v;
                }
            }
        }
        size_t base_layer;
        size_t base_key = to_key_s(sol, sol->base_state, &base_layer);

        printf("Saving...\n");  // TODO: Prevent data corruption by catching Ctrl+C.
        FILE *f = fopen(filename, "wb");
        save_solution(sol, f);
        fclose(f);
        print_node(negamax_node(sol, sol->base_state, base_key, base_layer, 0));
        // Verify solution integrity. For debugging only. Leaks memory.
        // char *buffer = file_to_buffer(filename);
        // buffer = load_solution(sol, buffer, 0);
    }
}
Example #8
0
File: elim.c Project: IEDMS/BNT-SM
void find_roots(Neighborhood * graph, Map remaining, Map roots){

  word w;
  Iterator iter = get_Iterator(remaining);

  while(!is_empty(iter)){
    w = next_key(iter);
    if(get_size_Map(graph[w.i]->parents) == 0){
      put(roots, w, w);
    }
  }
}
Example #9
0
File: elim.c Project: IEDMS/BNT-SM
unsigned long hash_set(word w){

  Map map = (Map) w.v;
  Iterator iter = get_Iterator(map);
  unsigned long h = 0;
 
  while(!is_empty(iter)){
    w = next_key(iter);
    h += (1 << w.i);
  }
  return h;
}
Example #10
0
void uplist(IX_DESC *name)            /* list keys in ascending order */
{
    ENTRY ee;
    int count = 0;
    first_key(name);
    while (next_key(&ee, name) == IX_OK) 
    {
        printf("%s\n",ee.key);
        ++count;
    }
    printf("uplist total key is %d.\n", count);
    /*printf("\nPress any key to continue \n");*/
    /*getchar();*/
}
Example #11
0
void aes128k128d(unsigned char *key, unsigned char *data, unsigned char *ciphertext)
{
    int round;
    int i;
    unsigned char intermediatea[16];
    unsigned char intermediateb[16];
    unsigned char round_key[16];

    for(i=0; i<16; i++) round_key[i] = key[i];

    for (round = 0; round < 11; round++)
    {
        if (round == 0)
        {
            xor_128(round_key, data, ciphertext);
            next_key(round_key, round);
        }
        else if (round == 10)
        {
            byte_sub(ciphertext, intermediatea);
            shift_row(intermediatea, intermediateb);
            xor_128(intermediateb, round_key, ciphertext);
        }
        else    /* 1 - 9 */
        {
            byte_sub(ciphertext, intermediatea);
            shift_row(intermediatea, intermediateb);
            mix_column(&intermediateb[0], &intermediatea[0]);
            mix_column(&intermediateb[4], &intermediatea[4]);
            mix_column(&intermediateb[8], &intermediatea[8]);
            mix_column(&intermediateb[12], &intermediatea[12]);
            xor_128(intermediatea, round_key, ciphertext);
            next_key(round_key, round);
        }
    }

}
Example #12
0
int locate_key(ENTRY *pe, IX_DESC *pix)
{
    int ret;
    //ENTRY e;
    ret = find_ix(pe, pix, 1);
    if (ret) 
    {
        copy_entry(pe, ENT_ADR(block_ptr, CO(pci->level)));
    }
    else if (next_key(pe,pix) == EOIX) 
    {
        ret = EOIX;
    }

    return ret;
} 
Example #13
0
File: mtree.c Project: taysom/tau
static int next_key(struct iterator_mtree *imt, u64 blknum)
{
	struct block *b;
	u64 key = imt->key;
	int i;
	int rc;

	if (!blknum)
		return DONE;
	b = get_blk(imt->mt->dev, blknum);

	if (isLeaf(b)) {
		struct leaf *leaf = b->buf;
		struct record *rec = (struct record *)leaf->data;

		for (i = 0; i < leaf->num_recs; i++, rec++) {
			if (key < rec->key) {
				imt->key = rec->key;
				imt->val.size = rec->size;
				memcpy(imt->data,
					&leaf->data[rec->offset],
					rec->size);
				put_blk(b);
				return 0;
			}
		}
		put_blk(b);
		return NEXT;
	} else {
		struct branch *branch = b->buf;
		struct twig *twig = branch->twig;
		
		for (i = 0; i < branch->num_twigs - 1; i++, twig++) {
			if (key < twig[1].key)
				break;
		}
		for (; i < branch->num_twigs; i++, twig++) {
			rc = next_key(imt, twig->blknum);
			if (rc == 0) {
				put_blk(b);
				return 0;
			}
		}
		put_blk(b);
		return NEXT;
	}
}
Example #14
0
static void text_scan_security(struct connection *conn)
{
	struct iscsi_login_rsp_hdr *rsp = (struct iscsi_login_rsp_hdr *)&conn->rsp.bhs;
	char *key, *value, *data, *nextValue;
	int datasize;

	data = conn->req.data;
	datasize = conn->req.datasize;

	while ((key = next_key(&data, &datasize, &value))) {
		if (!(param_index_by_name(key, login_keys) < 0))
			;
		else if (!strcmp(key, "AuthMethod")) {
			do {
				nextValue = strchr(value, ',');
				if (nextValue)
					*nextValue++ = 0;

				if (!strcmp(value, "None")) {
					if (!account_empty(conn->tid, AUTH_DIR_INCOMING))
						continue;
					conn->auth_method = AUTH_NONE;
					text_key_add(conn, key, "None");
					break;
				} else if (!strcmp(value, "CHAP")) {
					if (account_empty(conn->tid, AUTH_DIR_INCOMING))
						continue;
					conn->auth_method = AUTH_CHAP;
					text_key_add(conn, key, "CHAP");
					break;
				}
			} while ((value = nextValue));

			if (conn->auth_method == AUTH_UNKNOWN)
				text_key_add_reject(conn, key);
		} else
			text_key_add(conn, key, "NotUnderstood");
	}
	if (conn->auth_method == AUTH_UNKNOWN) {
		rsp->status_class = ISCSI_STATUS_INITIATOR_ERR;
		rsp->status_detail = ISCSI_STATUS_AUTH_FAILED;
		conn->state = STATE_EXIT;
	}
}
Example #15
0
static void text_scan_text(struct connection *conn)
{
	char *key, *value, *data;
	int datasize;

	data = conn->req.data;
	datasize = conn->req.datasize;

	while ((key = next_key(&data, &datasize, &value))) {
		if (!strcmp(key, "SendTargets")) {
			struct sockaddr_storage ss;
			socklen_t slen, blen;
			char *p, buf[NI_MAXHOST + 128];

			if (value[0] == 0)
				continue;

			p = buf;
			blen = sizeof(buf);

			slen = sizeof(ss);
			getsockname(conn->fd, (struct sockaddr *) &ss, &slen);
			if (ss.ss_family == AF_INET6) {
				*p++ = '[';
				blen--;
			}

			slen = sizeof(ss);
			getnameinfo((struct sockaddr *) &ss, slen, p, blen,
				    NULL, 0, NI_NUMERICHOST);

			p = buf + strlen(buf);

			if (ss.ss_family == AF_INET6)
				 *p++ = ']';

			sprintf(p, ":%d,1", server_port);
			target_list_build(conn, buf,
					  strcmp(value, "All") ? value : NULL);
		} else
			text_key_add(conn, key, "NotUnderstood");
	}
}
Example #16
0
void main()
{	struct block data,key,temp;
	//unsigned char c1[16]={0x32,0x88,0x31,0xe0,0x43,0x5a,0x31,0x37,0xf6,0x30,0x98,0x07,0xa8,0x8d,0xa2,0x34};
	//unsigned char c2[16]={0x2b,0x28,0xab,0x09,0x7e,0xae,0xf7,0xcf,0x15,0xd2,0x15,0x4f,0x16,0xa6,0x88,0x3c};
	unsigned char c1[16]="Hello World. 123";
	unsigned char c2[16]="My New Password.";	
	int i,j,c=0;
	struct block round_key[11];
	// Initializing Data and Key
	for(i=0;i<4;i++)
	{	for(j=0;j<4;j++)
		{	data.b[i][j]=c1[c];
			key.b[i][j]=c2[c];
			c++;	
		}
	}

	printf("Data and key before encryption:");
	printf("\n Data:\n");
	print_block(data);
	printf("\n Key:\n");
	print_block(key);

	printf("Generating All the round Keys:");
	round_key[0]=key;
	temp=key;	
	for(i=0;i<10;i++)
	{	temp=next_key(temp,i);
		round_key[i+1]=temp;
	}
	printf("All the keys generated.");

	data=encrypt(data,round_key);

	printf("Data after encryption:");
	printf("\n Data:\n");
	print_block(data);

	printf("\nData After Decryption\n");
	data=decrypt(data,round_key);
	print_block(data);
}
Example #17
0
File: elim.c Project: IEDMS/BNT-SM
int is_clique(int node, Map * adj_list, int size){

  word w, w2;
  Map map = create_Map(size, compare, hash_int, empty(), 1);
  Iterator iter = get_Iterator(adj_list[node]);

  while(!is_empty(iter)){
    w = next_value(iter);
    w2.i = ((Node) w.v)->index;
    put(map, w2, w);
  }
  while(get_size_Map(map) > 0){
    iter = get_Iterator(map);
    w = next_key(iter);
    rem(map, w);
    if(!is_subset_of(map, adj_list[w.i])){
      destroy_Map(map);
      return 0;
    }
  }
  destroy_Map(map);
  return 1;
}
Example #18
0
std::size_t run_test(rocksdb::DB* db, std::size_t(*next_key)(std::size_t, std::size_t), std::size_t count){
    auto start = cclock::now();
//auto test_count = count / 10;
    auto test_count = count;
    rocksdb::Status status;
    std::string data;

    std::cout << "get: " << test_count << " documents" << std::endl;
    auto read_options = rocksdb::ReadOptions();

    std::size_t key = 1;
    for(std::size_t i = 0 ; i < test_count ; ++i){
        status =  db->Get(read_options, std::to_string(key), &data);
        key = next_key(key, count);

	if(i<10){ std::cout << key <<  " -- " << data << std::endl; }
    }


    auto duration = std::chrono::duration_cast<std::chrono::seconds>(cclock::now() - start);

    return duration.count();
}
Example #19
0
int main(int ac, char **av) {
	struct btrfs_key ins;
	struct btrfs_key last = { (u64)-1, 0, 0};
	char *buf;
	int i;
	int num;
	int ret;
	int run_size = 300000;
	int max_key =  100000000;
	int tree_size = 2;
	struct btrfs_path path;
	struct btrfs_root *root;
	struct btrfs_trans_handle *trans;

	buf = malloc(512);
	memset(buf, 0, 512);

	radix_tree_init();

	root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, OPEN_CTREE_WRITES);
	if (!root) {
		fprintf(stderr, "Open ctree failed\n");
		exit(1);
	}
	trans = btrfs_start_transaction(root, 1);
	srand(55);
	btrfs_set_key_type(&ins, BTRFS_STRING_ITEM_KEY);
	for (i = 0; i < run_size; i++) {
		num = next_key(i, max_key);
		// num = i;
		sprintf(buf, "string-%d", num);
		if (i % 10000 == 0)
			fprintf(stderr, "insert %d:%d\n", num, i);
		ins.objectid = num;
		ins.offset = 0;
		ret = btrfs_insert_item(trans, root, &ins, buf, 512);
		if (!ret)
			tree_size++;
		if (i == run_size - 5) {
			btrfs_commit_transaction(trans, root);
			trans = btrfs_start_transaction(root, 1);
		}
	}
	btrfs_commit_transaction(trans, root);
	close_ctree(root);
	exit(1);
	root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, OPEN_CTREE_WRITES);
	if (!root) {
		fprintf(stderr, "Open ctree failed\n");
		exit(1);
	}
	printf("starting search\n");
	srand(55);
	for (i = 0; i < run_size; i++) {
		num = next_key(i, max_key);
		ins.objectid = num;
		btrfs_init_path(&path);
		if (i % 10000 == 0)
			fprintf(stderr, "search %d:%d\n", num, i);
		ret = btrfs_search_slot(NULL, root, &ins, &path, 0, 0);
		if (ret) {
			btrfs_print_tree(root, root->node, 1);
			printf("unable to find %d\n", num);
			exit(1);
		}
		btrfs_release_path(&path);
	}
	close_ctree(root);

	root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, OPEN_CTREE_WRITES);
	if (!root) {
		fprintf(stderr, "Open ctree failed\n");
		exit(1);
	}
	printf("node %p level %d total ptrs %d free spc %lu\n", root->node,
	        btrfs_header_level(root->node),
		btrfs_header_nritems(root->node),
		(unsigned long)BTRFS_NODEPTRS_PER_BLOCK(root) -
		btrfs_header_nritems(root->node));
	printf("all searches good, deleting some items\n");
	i = 0;
	srand(55);
	trans = btrfs_start_transaction(root, 1);
	for (i = 0 ; i < run_size/4; i++) {
		num = next_key(i, max_key);
		ins.objectid = num;
		btrfs_init_path(&path);
		ret = btrfs_search_slot(trans, root, &ins, &path, -1, 1);
		if (!ret) {
			if (i % 10000 == 0)
				fprintf(stderr, "del %d:%d\n", num, i);
			ret = btrfs_del_item(trans, root, &path);
			if (ret != 0)
				BUG();
			tree_size--;
		}
		btrfs_release_path(&path);
	}
	btrfs_commit_transaction(trans, root);
	close_ctree(root);

	root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, OPEN_CTREE_WRITES);
	if (!root) {
		fprintf(stderr, "Open ctree failed\n");
		exit(1);
	}
	trans = btrfs_start_transaction(root, 1);
	srand(128);
	for (i = 0; i < run_size; i++) {
		num = next_key(i, max_key);
		sprintf(buf, "string-%d", num);
		ins.objectid = num;
		if (i % 10000 == 0)
			fprintf(stderr, "insert %d:%d\n", num, i);
		ret = btrfs_insert_item(trans, root, &ins, buf, 512);
		if (!ret)
			tree_size++;
	}
	btrfs_commit_transaction(trans, root);
	close_ctree(root);

	root = open_ctree(av[1], BTRFS_SUPER_INFO_OFFSET, OPEN_CTREE_WRITES);
	if (!root) {
		fprintf(stderr, "Open ctree failed\n");
		exit(1);
	}
	srand(128);
	printf("starting search2\n");
	for (i = 0; i < run_size; i++) {
		num = next_key(i, max_key);
		ins.objectid = num;
		btrfs_init_path(&path);
		if (i % 10000 == 0)
			fprintf(stderr, "search %d:%d\n", num, i);
		ret = btrfs_search_slot(NULL, root, &ins, &path, 0, 0);
		if (ret) {
			btrfs_print_tree(root, root->node, 1);
			printf("unable to find %d\n", num);
			exit(1);
		}
		btrfs_release_path(&path);
	}
	printf("starting big long delete run\n");
	trans = btrfs_start_transaction(root, 1);
	while(root->node && btrfs_header_nritems(root->node) > 0) {
		struct extent_buffer *leaf;
		int slot;
		ins.objectid = (u64)-1;
		btrfs_init_path(&path);
		ret = btrfs_search_slot(trans, root, &ins, &path, -1, 1);
		if (ret == 0)
			BUG();

		leaf = path.nodes[0];
		slot = path.slots[0];
		if (slot != btrfs_header_nritems(leaf))
			BUG();
		while(path.slots[0] > 0) {
			path.slots[0] -= 1;
			slot = path.slots[0];
			leaf = path.nodes[0];

			btrfs_item_key_to_cpu(leaf, &last, slot);

			if (tree_size % 10000 == 0)
				printf("big del %d:%d\n", tree_size, i);
			ret = btrfs_del_item(trans, root, &path);
			if (ret != 0) {
				printf("del_item returned %d\n", ret);
				BUG();
			}
			tree_size--;
		}
		btrfs_release_path(&path);
	}
	/*
	printf("previous tree:\n");
	btrfs_print_tree(root, root->commit_root);
	printf("map before commit\n");
	btrfs_print_tree(root->extent_root, root->extent_root->node);
	*/
	btrfs_commit_transaction(trans, root);
	printf("tree size is now %d\n", tree_size);
	printf("root %p commit root %p\n", root->node, root->commit_root);
	btrfs_print_tree(root, root->node, 1);
	close_ctree(root);
	return 0;
}
Example #20
0
void iterate(
        dict *d, lin_dict *ko_ld,
        node_value *base_nodes, node_value *pass_nodes, node_value *ko_nodes, value_t *leaf_nodes,
        state *s, size_t key_min, int japanese_rules
    ) {
    state child_;
    state *child = &child_;

    size_t num_states = num_keys(d);

    int changed = 1;
    while (changed) {
        changed = 0;
        size_t key = key_min;
        for (size_t i = 0; i < 2 * num_states + ko_ld->num_keys; i++) {
            if (i < 2 * num_states) {
                assert(from_key(s, key));
                if (i % 2 == 1) {
                    s->passes = 1;
                }
            }
            else {
                key = ko_ld->keys[i - 2 * num_states];
                size_t ko_pos = key % STATE_SIZE;
                key /= STATE_SIZE;
                assert(from_key(s, key));
                s->ko = 1UL << ko_pos;
            }
            node_value new_v = (node_value) {VALUE_MIN, VALUE_MIN, DISTANCE_MAX, 0};
            for (int j = -1; j < STATE_SIZE; j++) {
                size_t child_key;
                node_value child_v;
                *child = *s;
                stones_t move;
                if (j == -1){
                    move = 0;
                }
                else {
                    move = 1UL << j;
                }
                if (make_move(child, move)) {
                    canonize(child);
                    child_key = to_key(child);
                    if (child->passes == 2){
                        value_t score = leaf_nodes[key_index(d, child_key)];
                        child_v = (node_value) {score, score, 0, 0};
                    }
                    else if (child->passes == 1) {
                        child_v = pass_nodes[key_index(d, child_key)];
                    }
                    else if (child->ko) {
                        child_key = child_key * STATE_SIZE + bitscan(child->ko);
                        child_v = ko_nodes[lin_key_index(ko_ld, child_key)];
                    }
                    else {
                        child_v = base_nodes[key_index(d, child_key)];
                    }
                    if (japanese_rules) {
                        int prisoners = (popcount(s->opponent) - popcount(child->player)) * PRISONER_VALUE;
                        if (child_v.low > VALUE_MIN) {
                            child_v.low = child_v.low - prisoners;
                        }
                        if (child_v.high < VALUE_MAX) {
                            child_v.high = child_v.high - prisoners;
                        }
                    }
                    new_v = negamax(new_v, child_v);
                }
            }
            assert(new_v.high_distance > 0);
            if (i < 2 * num_states) {
                if (i % 2 == 0) {
                    assert(new_v.low_distance > 1);
                    assert(new_v.high_distance > 1);
                    assert(new_v.low >= base_nodes[i / 2].low);
                    assert(new_v.high <= base_nodes[i / 2].high);
                    changed = changed || !equal(base_nodes[i / 2], new_v);
                    base_nodes[i / 2] = new_v;
                }
                else {
                    changed = changed || !equal(pass_nodes[i / 2], new_v);
                    pass_nodes[i / 2] = new_v;
                    key = next_key(d, key);
                }
            }
            else {
                changed = changed || !equal(ko_nodes[i - 2 * num_states], new_v);
                ko_nodes[i - 2 * num_states] = new_v;
            }
        }
        print_node(base_nodes[0]);
    }
    for (size_t i = 0; i < ko_ld->num_keys; i++) {
        assert(ko_nodes[i].low_distance > 2);
        assert(ko_nodes[i].high_distance > 2);
    }

    for (size_t i = 0; i < num_states; i++) {
        assert(base_nodes[i].low_distance > 1);
        assert(base_nodes[i].high_distance > 1);
        assert(pass_nodes[i].low_distance > 0);
        assert(pass_nodes[i].high_distance > 0);
    }
}
Example #21
0
int main(int argc, char *argv[]) {
    if (argc != 3) {
        printf("Usage: %s width height\n", argv[0]);
        return 0;
    }
    int width = atoi(argv[1]);
    int height = atoi(argv[2]);
    if (width <= 0) {
        printf("Width must be larger than 0.\n");
        return 0;
    }
    if (width >= 7) {
        printf("Width must be less than 7.\n");
        return 0;
    }
    if (height <= 0) {
        printf("Height must be larger than 0.\n");
        return 0;
    }
    if (height >= 6) {
        printf("Height must be less than 6.\n");
        return 0;
    }

    state s_ = (state) {rectangle(width, height), 0, 0, 0, 0};
    state *s = &s_;

    dict d_;
    dict *d = &d_;

    size_t max_k = max_key(s);
    init_dict(d, max_k);

    size_t key_min = ~0;
    size_t key_max = 0;

    size_t total_legal = 0;
    for (size_t k = 0; k < max_k; k++) {
        if (!from_key(s, k)){
            continue;
        }
        total_legal++;
        canonize(s);
        size_t key = to_key(s);
        add_key(d, key);
        if (key < key_min) {
            key_min = key;
        }
        if (key > key_max) {
            key_max = key;
        }
    }
    resize_dict(d, key_max);
    finalize_dict(d);
    size_t num_states = num_keys(d);

    printf("Total legal positions %zu\n", total_legal);
    printf("Total unique positions %zu\n", num_states);

    node_value *base_nodes = (node_value*) malloc(num_states * sizeof(node_value));
    node_value *pass_nodes = (node_value*) malloc(num_states * sizeof(node_value));
    value_t *leaf_nodes = (value_t*) malloc(num_states * sizeof(value_t));

    lin_dict ko_ld_ = (lin_dict) {0, 0, 0, NULL};
    lin_dict *ko_ld = &ko_ld_;

    state child_;
    state *child = &child_;
    size_t child_key;
    size_t key = key_min;
    for (size_t i = 0; i < num_states; i++) {
        assert(from_key(s, key));
        value_t score = liberty_score(s);
        leaf_nodes[i] = score;
        pass_nodes[i] = (node_value) {VALUE_MIN, VALUE_MAX, DISTANCE_MAX, DISTANCE_MAX};
        base_nodes[i] = (node_value) {VALUE_MIN, VALUE_MAX, DISTANCE_MAX, DISTANCE_MAX};
        for (int j = 0; j < STATE_SIZE; j++) {
            *child = *s;
            if (make_move(child, 1UL << j)) {
                if (child->ko) {
                    canonize(child);
                    child_key = to_key(child) * STATE_SIZE + bitscan(child->ko);
                    add_lin_key(ko_ld, child_key);
                }
            }
        }
        key = next_key(d, key);
    }

    finalize_lin_dict(ko_ld);

    node_value *ko_nodes = (node_value*) malloc(ko_ld->num_keys * sizeof(node_value));
    printf("Unique positions with ko %zu\n", ko_ld->num_keys);

    for (size_t i = 0; i < ko_ld->num_keys; i++) {
        ko_nodes[i] = (node_value) {VALUE_MIN, VALUE_MAX, DISTANCE_MAX, DISTANCE_MAX};
    }

    #ifndef PRELOAD
    printf("Negamax with Chinese rules.\n");
    iterate(
        d, ko_ld,
        base_nodes, pass_nodes, ko_nodes, leaf_nodes,
        s, key_min, 0
    );
    #endif

    char dir_name[16];
    sprintf(dir_name, "%dx%d", width, height);
    struct stat sb;
    if (stat(dir_name, &sb) == -1) {
        mkdir(dir_name, 0700);
    }
    assert(chdir(dir_name) == 0);
    FILE *f;

    #ifndef PRELOAD
    f = fopen("d_slots.dat", "wb");
    fwrite((void*) d->slots, sizeof(slot_t), d->num_slots, f);
    fclose(f);
    f = fopen("d_checkpoints.dat", "wb");
    fwrite((void*) d->checkpoints, sizeof(size_t), (d->num_slots >> 4) + 1, f);
    fclose(f);
    f = fopen("ko_ld_keys.dat", "wb");
    fwrite((void*) ko_ld->keys, sizeof(size_t), ko_ld->num_keys, f);
    fclose(f);

    f = fopen("base_nodes.dat", "wb");
    fwrite((void*) base_nodes, sizeof(node_value), num_states, f);
    fclose(f);
    f = fopen("pass_nodes.dat", "wb");
    fwrite((void*) pass_nodes, sizeof(node_value), num_states, f);
    fclose(f);
    f = fopen("leaf_nodes.dat", "wb");
    fwrite((void*) leaf_nodes, sizeof(value_t), num_states, f);
    fclose(f);
    f = fopen("ko_nodes.dat", "wb");
    fwrite((void*) ko_nodes, sizeof(node_value), ko_ld->num_keys, f);
    fclose(f);
    #endif

    #ifdef PRELOAD
    f = fopen("base_nodes.dat", "rb");
    fread((void*) base_nodes, sizeof(node_value), num_states, f);
    fclose(f);
    f = fopen("pass_nodes.dat", "rb");
    fread((void*) pass_nodes, sizeof(node_value), num_states, f);
    fclose(f);
    f = fopen("leaf_nodes.dat", "rb");
    fread((void*) leaf_nodes, sizeof(value_t), num_states, f);
    fclose(f);
    f = fopen("ko_nodes.dat", "rb");
    fread((void*) ko_nodes, sizeof(node_value), ko_ld->num_keys, f);
    fclose(f);
    #endif

    // Japanese leaf state calculation.
    state new_s_;
    state *new_s = &new_s_;
    key = key_min;
    for (size_t i = 0; i < num_states; i++) {
        assert(from_key(s, key));
        stones_t empty = s->playing_area & ~(s->player | s->opponent);

        *new_s = *s;
        endstate(
            d, ko_ld,
            base_nodes, pass_nodes, ko_nodes,
            new_s, base_nodes[i], 0, 1
        );

        stones_t player_controlled = new_s->player | liberties(new_s->player, new_s->playing_area & ~new_s->opponent);
        stones_t opponent_controlled = new_s->opponent | liberties(new_s->opponent, new_s->playing_area & ~new_s->player);
        value_t score = popcount(player_controlled & empty) - popcount(opponent_controlled & empty);
        score += 2 * (popcount(player_controlled & s->opponent) - popcount(opponent_controlled & s->player));
        leaf_nodes[i] = score;

        *new_s = *s;
        endstate(
            d, ko_ld,
            base_nodes, pass_nodes, ko_nodes,
            new_s, base_nodes[i], 0, 0
        );

        player_controlled = new_s->player | liberties(new_s->player, new_s->playing_area & ~new_s->opponent);
        opponent_controlled = new_s->opponent | liberties(new_s->opponent, new_s->playing_area & ~new_s->player);
        score = popcount(player_controlled & empty) - popcount(opponent_controlled & empty);
        score += 2 * (popcount(player_controlled & s->opponent) - popcount(opponent_controlled & s->player));
        leaf_nodes[i] += score;

        key = next_key(d, key);
    }

    // Clear the rest of the tree.
    for (size_t i = 0; i < num_states; i++) {
        pass_nodes[i] = (node_value) {VALUE_MIN, VALUE_MAX, DISTANCE_MAX, DISTANCE_MAX};
        base_nodes[i] = (node_value) {VALUE_MIN, VALUE_MAX, DISTANCE_MAX, DISTANCE_MAX};
    }
    for (size_t i = 0; i < ko_ld->num_keys; i++) {
        ko_nodes[i] = (node_value) {VALUE_MIN, VALUE_MAX, DISTANCE_MAX, DISTANCE_MAX};
    }

    printf("Negamax with Japanese rules.\n");
    iterate(
        d, ko_ld,
        base_nodes, pass_nodes, ko_nodes, leaf_nodes,
        s, key_min, 1
    );

    f = fopen("base_nodes_j.dat", "wb");
    fwrite((void*) base_nodes, sizeof(node_value), num_states, f);
    fclose(f);
    f = fopen("pass_nodes_j.dat", "wb");
    fwrite((void*) pass_nodes, sizeof(node_value), num_states, f);
    fclose(f);
    f = fopen("leaf_nodes_j.dat", "wb");
    fwrite((void*) leaf_nodes, sizeof(value_t), num_states, f);
    fclose(f);
    f = fopen("ko_nodes_j.dat", "wb");
    fwrite((void*) ko_nodes, sizeof(node_value), ko_ld->num_keys, f);
    fclose(f);

    return 0;
}
Example #22
0
File: elim.c Project: IEDMS/BNT-SM
/*
    if can find adj_list[i] that is a clique
      remove i, all edges from i;
      ordering[o++] = i;
      cliques[c++] = adj_list[i];
    else find adj_list[i] with smallest clique weight
      remove i, all edges from i;
      ordering[o++] = i;
      make adj_list[i] a clique;
      cliques[c++] = adj_list[i];
*/
Elimination elim(int size, Map * adj_list, Neighborhood * partial_order,
    Map node_map){

  Map ordering, cliques, max_cliques, trashcan;
  int i, j, clique_exists, min_node, subset, index1, index2;
  float min_weight, weight;
  word w, w2, child, child2;
  Iterator iter, iter2;
  Map nodes = create_Map(size, compare, hash_int, empty(), 1);
  Map roots = create_Map(size, compare, hash_int, empty(), 1);
  int ** fill_ins;

  fill_ins = (int **) malloc(sizeof(int *) * size);
  fill_ins[0] = (int *) malloc(sizeof(int) * size * size);

  for(i = 1; i < size; i++){
    fill_ins[i] = fill_ins[i - 1] + size;
  }
  for(i = 0; i < size; i++){
    for(j = 0; j < size; j++){
      fill_ins[i][j] = 0;
    }
  }

  for(i = 0; i < size; i++){
    w.i = i;
    put(nodes, w, w);
  }
  find_roots(partial_order, nodes, roots);

  ordering = create_Map(size + 1, compare, hash_int, empty(), 1);
  cliques = create_Map(size + 1, set_compare, hash_set, empty(), 1);

  while(get_size_Map(nodes) > 0){
    clique_exists = 0;
    iter = get_Iterator(roots);
    while(!is_empty(iter)){
      w = next_key(iter);
      if(is_clique_heuristic(w.i, adj_list) && is_clique(w.i, adj_list, size)){
        clique_exists = 1;
        break;
      }
    }
    if(!clique_exists){
      min_weight = LONG_MAX;
      iter = get_Iterator(roots);
      while(!is_empty(iter)){
        w = next_value(iter);
        weight = 0;
        iter2 = get_Iterator(adj_list[w.i]);
        while(!is_empty(iter2)){
          weight += ((Node) next_value(iter2).v)->weight;
        }
        if(weight < min_weight){
          min_weight = weight;
          min_node = w.i;
        }
      }
      w.i = min_node;
    }
    min_node = w.i;
    rem(nodes, w);
    remove_node(partial_order, w.i);
    empty_Map(roots);
    find_roots(partial_order, nodes, roots);
    put(ordering, w, w);
    child.v = adj_list[w.i];

    if(!find((Map) child.v, w)){
      child2.v = create_Node(w.i, 0);
      put(node_map, child2, child2);
      put((Map) child.v, w, child2);
    }
    child.v = copy_Map((Map) child.v);
    put(cliques, child, child);
    iter = get_Iterator(adj_list[min_node]);
    i = 0;
    while(!is_empty(iter)){
      child = next_value(iter);
      rem(adj_list[((Node) child.v)->index], w);
    }
    iter = create_Iterator(adj_list[min_node]);
    while(!is_empty(iter)){
      child = next_value(iter);
      index1 = ((Node) child.v)->index;
      w.i = index1;
      iter2 = get_Iterator(adj_list[min_node]);
      while(!is_empty(iter2)){
        child2 = next_value(iter2);
	index2 = ((Node) child2.v)->index;
	if(index1 != index2){
          w2.i = index2;
          if(index1 < index2 && !find(adj_list[index1], w2)){
            fill_ins[index1][index2] = 1;
	  }
          put(adj_list[index1], w2, child2);
        }
      }
    }
    destroy_Iterator(iter);
  }
  destroy_Map(nodes);
  destroy_Map(roots);

  max_cliques = create_Map(size, set_compare, hash_set, empty(), 2);
  trashcan = create_Map(size, set_compare, hash_set, empty(), 2);
  while(get_size_Map(cliques) > 0){
    iter = get_Iterator(cliques);
    child = next_key(iter);
    rem(cliques, child);
    subset = 0;
    while(!is_empty(iter)){
      child2 = next_key(iter);
      if(is_subset_of((Map) child2.v, (Map) child.v)){
        rem(cliques, child2);
	put(trashcan, child2, child2);
      } else if(is_subset_of((Map) child.v, (Map) child2.v)){
         subset = 1;
	 break;
      }
    }
    if(!subset){
      put(max_cliques, child, child);
    } else {
      put(trashcan, child, child);
    }
  }

  destroy_Map(cliques);
  iter = get_Iterator(trashcan);
  while(!is_empty(iter)){
    child = next_key(iter);
    destroy_Map((Map) child.v);
  }
  destroy_Map(trashcan);
  return create_Elimination(ordering, max_cliques, fill_ins, node_map);
}
Example #23
0
int main(int argc, char *argv[]) {
    #ifdef TEST
        test();
        return 0;
    #endif
    #ifdef REPAIR
        repair(argc, argv);
        return 0;
    #endif
    #ifdef UPGRADE
        upgrade(argc, argv);
        return 0;
    #endif

    int load_sol = 0;
    int resume_sol = 0;
    if (strcmp(argv[argc - 1], "load") == 0) {
        load_sol = 1;
        argc--;
    }
    if (strcmp(argv[argc - 1], "resume") == 0) {
        resume_sol = 1;
        argc--;
    }
    parse_args(argc - 1, argv + 1);

    int width = board_width;
    int height = board_height;
    if (board_width >= 10) {
        fprintf(stderr, "Width must be less than 10.\n");
        exit(EXIT_FAILURE);
    }
    if (board_height >= 8) {
        fprintf(stderr, "Height must be less than 8.\n");
        exit(EXIT_FAILURE);
    }

    #include "tsumego.c"

    state base_state_;
    state *base_state = &base_state_;

    char sol_name[64] = "unknown";
    char temp_filename[128];
    char filename[128];
    if (board_width > 0) {
        *base_state = (state) {rectangle(width, height), 0, 0, 0, 0};
        sprintf(sol_name, "%dx%d", width, height);
    }
    else {
        int i;
        int found = 0;

        for (i = 0; tsumego_infos[i].name; ++i) {
            if (!strcmp(tsumego_name, tsumego_infos[i].name)) {
                *base_state = *(tsumego_infos[i].state);
                strcpy(sol_name, tsumego_name);
                found = 1;
                break;
            }
        }
        if (!found) {
            fprintf(stderr, "unknown tsumego: `%s'\n", tsumego_name);
            exit(EXIT_FAILURE);
        }
    }
    base_state->ko_threats = ko_threats;

    sprintf(temp_filename, "%s_temp.dat", sol_name);


    state_info si_;
    state_info *si = &si_;
    init_state(base_state, si);

    if (si->color_symmetry) {
        num_layers = 2 * abs(base_state->ko_threats) + 1;
    }
    else if (num_layers <= 0) {
        num_layers = abs(base_state->ko_threats) + 1;
    }
    else {
        assert(num_layers >= abs(base_state->ko_threats) + 1);
    }

    print_state(base_state);
    for (int i = 0; i < si->num_external; i++) {
        print_stones(si->externals[i]);
    }
    printf(
        "width=%d height=%d c=%d v=%d h=%d d=%d\n",
        si->width,
        si->height,
        si->color_symmetry,
        si->mirror_v_symmetry,
        si->mirror_h_symmetry,
        si->mirror_d_symmetry
    );

    state s_;
    state *s = &s_;

    dict d_;
    dict *d = &d_;

    solution sol_;
    solution *sol = &sol_;
    sol->base_state = base_state;
    sol->si = si;
    sol->d = d;
    sol->num_layers = num_layers;
    size_t num_states;

    // Re-used at frontend. TODO: Allocate a different pointer.
    state child_;
    state *child = &child_;

    if (load_sol) {
        goto frontend;
    }

    if (resume_sol) {
        char *buffer = file_to_buffer(temp_filename);
        buffer = load_solution(sol, buffer, 1);
        num_states = num_keys(sol->d);
        if (sol->leaf_rule == japanese_double_liberty) {
            goto iterate_capture;
        }
        else {
            goto iterate_japanese;
        }
    }

    size_t k_size = key_size(sol->si);
    if (!sol->si->color_symmetry) {
        k_size *= 2;
    }
    init_dict(sol->d, k_size);

    size_t total_legal = 0;
    for (size_t k = 0; k < k_size; k++) {
        if (!from_key_s(sol, s, k, 0)){
            continue;
        }
        total_legal++;
        size_t layer;
        size_t key = to_key_s(sol, s, &layer);
        assert(layer == 0);
        add_key(sol->d, key);
    }
    finalize_dict(sol->d);
    num_states = num_keys(sol->d);

    printf("Total positions %zu\n", total_legal);
    printf("Total unique positions %zu\n", num_states);

    node_value **base_nodes = (node_value**) malloc(sol->num_layers * sizeof(node_value*));
    for (size_t i = 0; i < sol->num_layers; i++) {
        base_nodes[i] = (node_value*) malloc(num_states * sizeof(node_value));
    }
    value_t *leaf_nodes = (value_t*) malloc(num_states * sizeof(value_t));

    lin_dict ko_ld_ = (lin_dict) {0, 0, 0, NULL};
    lin_dict *ko_ld = &ko_ld_;

    sol->base_nodes = base_nodes;
    sol->leaf_nodes = leaf_nodes;
    sol->ko_ld = ko_ld;

    size_t child_key;
    size_t key = sol->d->min_key;
    for (size_t i = 0; i < num_states; i++) {
        assert(from_key_s(sol, s, key, 0));
        // size_t layer;
        // assert(to_key_s(sol, s, &layer) == key);
        sol->leaf_nodes[i] = 0;
        for (size_t k = 0; k < sol->num_layers; k++) {
            (sol->base_nodes[k])[i] = (node_value) {VALUE_MIN, VALUE_MAX, DISTANCE_MAX, DISTANCE_MAX};
        }
        for (int j = 0; j < STATE_SIZE; j++) {
            *child = *s;
            int prisoners;
            if (make_move(child, 1ULL << j, &prisoners)) {
                if (target_dead(child)) {
                    continue;
                }
                if (child->ko) {
                    size_t child_layer;
                    child_key = to_key_s(sol, child, &child_layer);
                    add_lin_key(sol->ko_ld, child_key);
                }
            }
        }
        key = next_key(sol->d, key);
    }

    finalize_lin_dict(sol->ko_ld);

    node_value **ko_nodes = (node_value**) malloc(sol->num_layers * sizeof(node_value*));
    sol->ko_nodes = ko_nodes;
    for (size_t i = 0; i < sol->num_layers; i++) {
        sol->ko_nodes[i] = (node_value*) malloc(sol->ko_ld->num_keys * sizeof(node_value));
    }
    printf("Unique positions with ko %zu\n", sol->ko_ld->num_keys);

    for (size_t i = 0; i < sol->ko_ld->num_keys; i++) {
        for (size_t k = 0; k < sol->num_layers; k++) {
            sol->ko_nodes[k][i] = (node_value) {VALUE_MIN, VALUE_MAX, DISTANCE_MAX, DISTANCE_MAX};
        }
    }

    #ifdef CHINESE
    printf("Negamax with Chinese rules.\n");
    sol->count_prisoners = 0;
    sol->leaf_rule = chinese_liberty;
    iterate(sol, temp_filename);
    #endif

    // NOTE: Capture rules may refuse to kill stones when the needed nakade sacrifices exceed triple the number of stones killed.
    printf("Negamax with capture rules.\n");
    sol->count_prisoners = 1;
    sol->leaf_rule = japanese_double_liberty;
    iterate_capture:
    iterate(sol, temp_filename);

    sprintf(filename, "%s_capture.dat", sol_name);
    FILE *f = fopen(filename, "wb");
    save_solution(sol, f);
    fclose(f);


    calculate_leaves(sol);

    // Clear the rest of the tree.
    for (size_t j = 0; j < sol->num_layers; j++) {
        for (size_t i = 0; i < num_states; i++) {
            sol->base_nodes[j][i] = (node_value) {VALUE_MIN, VALUE_MAX, DISTANCE_MAX, DISTANCE_MAX};
        }
        for (size_t i = 0; i < sol->ko_ld->num_keys; i++) {
            sol->ko_nodes[j][i] = (node_value) {VALUE_MIN, VALUE_MAX, DISTANCE_MAX, DISTANCE_MAX};
        }
    }

    printf("Negamax with Japanese rules.\n");
    sol->count_prisoners = 1;
    sol->leaf_rule = precalculated;
    iterate_japanese:
    iterate(sol, temp_filename);

    sprintf(filename, "%s_japanese.dat", sol_name);
    f = fopen(filename, "wb");
    save_solution(sol, f);
    fclose(f);

    frontend:
    if (load_sol) {
        sprintf(filename, "%s_japanese.dat", sol_name);
        char *buffer = file_to_buffer(filename);
        buffer = load_solution(sol, buffer, 1);
    }

    *s = *sol->base_state;

    char coord1;
    int coord2;

    int total_prisoners = 0;
    int turn = 0;

    while (1) {
        size_t layer;
        size_t key = to_key_s(sol, s, &layer);
        node_value v = negamax_node(sol, s, key, layer, 0);
        print_state(s);
        if (turn) {
            print_node((node_value) {total_prisoners - v.high, total_prisoners - v.low, v.high_distance, v.low_distance});
        }
        else {
            print_node((node_value) {total_prisoners + v.low, total_prisoners + v.high, v.low_distance, v.high_distance});
        }
        if (target_dead(s) || s->passes >= 2) {
            break;
        }
        for (int j = -1; j < STATE_SIZE; j++) {
            *child = *s;
            stones_t move;
            if (j == -1){
                move = 0;
            }
            else {
                move = 1ULL << j;
            }
            char c1 = 'A' + (j % WIDTH);
            char c2 = '0' + (j / WIDTH);
            int prisoners;
            if (make_move(child, move, &prisoners)) {
                size_t child_layer;
                size_t child_key = to_key_s(sol, child, &child_layer);
                node_value child_v = negamax_node(sol, child, child_key, child_layer, 0);
                if (sol->count_prisoners) {
                    if (child_v.low > VALUE_MIN && child_v.low < VALUE_MAX) {
                        child_v.low = child_v.low - prisoners;
                    }
                    if (child_v.high > VALUE_MIN && child_v.high < VALUE_MAX) {
                        child_v.high = child_v.high - prisoners;
                    }
                }
                if (move) {
                    printf("%c%c", c1, c2);
                }
                else {
                    printf("pass");
                }
                if (-child_v.high == v.low) {
                    printf("-");
                    if (child_v.high_distance + 1 == v.low_distance) {
                        printf("L");
                    }
                    else {
                        printf("l");
                    }
                }
                if (-child_v.high == v.low) {
                    printf("-");
                    if (child_v.low_distance + 1 == v.high_distance) {
                        printf("H");
                    }
                    else {
                        printf("h");
                    }
                }
                printf(" ");
            }
        }
        printf("\n");
        printf("Enter coordinates:\n");
        assert(scanf("%c %d", &coord1, &coord2));
        int c;
        while ((c = getchar()) != '\n' && c != EOF);
        coord1 = tolower(coord1) - 'a';
        stones_t move;
        if (coord1 < 0 || coord1 >= WIDTH) {
            // printf("%d, %d\n", coord1, coord2);
            move = 0;
        }
        else {
            move = 1ULL << (coord1 + V_SHIFT * coord2);
        }
        int prisoners;
        if (make_move(s, move, &prisoners)) {
            if (turn) {
                total_prisoners -= prisoners;
            }
            else {
                total_prisoners += prisoners;
            }
            turn = !turn;
        }
    }

    return 0;
}
Example #24
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){

  int dims [2];
  int i, j, k, m, n;
  long index;
  double * G_pr;
  double * stage_pr;
  double * answer_G_pr, * fill_ins_pr;
  double * matlab_clique_pr;
  mxArray * matlab_clique;
  Elimination e;
  float ** adj_mat;
  int ** order = (int **) NULL;
  Iterator iter, iter2;
  word w, w2;
  int ** fill_ins;
  Map cliques;
  Map clique;
  mxArray * fill_ins_mat;
  int * nodes;
  mxArray * full;

  full = mlfFull((mxArray *) prhs[0]);
  /* Obtain graph matrix information. */
  m = mxGetM(full);
  n = mxGetN(full);
  G_pr = mxGetPr(full);

  if(n < 1 || m < 1){
    return;
  }

  /* Allocate and populate the log weight adjacency matrix corresponding
     to the input graph. */
  adj_mat = (float **) malloc(sizeof(float *) * m);
  adj_mat[0] = (float *) malloc(sizeof(float) * m * n);
  for(i = 1; i < m; i++){
    adj_mat[i] = adj_mat[i - 1] + n;
  }
  /* We no longer have log weight info, but we have a (total) ordering on
     the nodes already, so we do not need this information. */
  for(i = 0; i < m; i++){
    for(j = 0; j < n; j++){
      index = j * m + i;
      if(G_pr[index] > 0){
        adj_mat[i][j] = 1;
      } else {
        adj_mat[i][j] = 0;
      }
    }
  }

  /* Convert the total elimination ordering into a partial order argument
     for the elimination routine.  The elimination routine's purpose in this
     mode of operation is to return cliques and fill-in edges. */
  if(nrhs > 1){
    order = (int **) malloc(sizeof(int *) * m);
    order[0] = (int *) malloc(sizeof(int) * m * n);
    for(i = 1; i < m; i++){
      order[i] = order[i - 1] + n;
    }
    for(i = 0; i < m; i++){
      for(j = 0; j < n; j++){
        order[i][j] = 0;
      }
    }
    stage_pr = mxGetPr(prhs[1]);
    for(i = 0; i < mxGetN(prhs[1]) - 1; i++){
      order[(int) stage_pr[i] - 1][(int) stage_pr[i + 1] - 1] = 1;
    }
  }

  /* Find the elimination ordering. */
  e = find_elim(n, adj_mat, order, -1);

  /* Allocate memory for the answer, and set the answer. */
  plhs[0] = mxCreateDoubleMatrix(m, n, mxREAL);
  answer_G_pr = mxGetPr(plhs[0]);
  cliques = get_cliques(e);
/* 
  dims[0] = 1;
  dims[1] = get_size_Map(cliques);
  plhs[1] = mxCreateCellArray(2, (const int *) dims);*/
  plhs[1] = mxCreateCellMatrix(get_size_Map(cliques), 1);
  fill_ins = get_fill_ins(e);
  fill_ins_mat = mxCreateDoubleMatrix(m, n, mxREAL);
  fill_ins_pr = mxGetPr(fill_ins_mat);

  for(i = 0; i < n; i++){
    for(j = 0; j < m; j++){
      index = j * m + i;
      answer_G_pr[index] = G_pr[index];
      if(fill_ins[i][j] > 0){
        answer_G_pr[index] = 1;
        fill_ins_pr[index] = 1;
      }
    }
  }
  mxDestroyArray(full);
  plhs[2] = mlfSparse(fill_ins_mat, NULL, NULL, NULL, NULL, NULL);
  mxDestroyArray(fill_ins_mat);
  nodes = (int *) malloc(sizeof(int) * n);
  k = 0;
  iter = get_Iterator(cliques);
  while(!is_empty(iter)){
    w = next_key(iter);
    clique = (Map) w.v;
    matlab_clique = mxCreateDoubleMatrix(1, get_size_Map(clique), mxREAL);
    matlab_clique_pr = mxGetPr(matlab_clique);
    for(i = 0; i < n; i++){
      nodes[i] = 0;
    }
    iter2 = get_Iterator(clique);
    while(!is_empty(iter2)){
      w2 = next_key(iter2);
      nodes[w2.i] = w2.i + 1;
    }
    j = 0;
    for(i = 0; i < n; i++){
      if(nodes[i] > 0){
        matlab_clique_pr[j++] = nodes[i];
      }
    }
    mxSetCell(plhs[1], k++, matlab_clique);
  }
  free(nodes);

  /* Finally, free the allocated memory. */
  destroy_Elimination(e);
  if(adj_mat){
    if(adj_mat[0]){
      free(adj_mat[0]);
    }
    free(adj_mat);
  }
  if(order){
    if(order[0]){
      free(order[0]);
    }
    free(order);
  }
}
Example #25
0
void
update_keys (FILE * keys)
{
  FILE *privring, *privlock;
  char line[1024];
  long pos;
  unsigned long exp, expmax;
  int sk = 0, pk = 0, tk = 0;

  mix_lock ("secring", &privlock);
  if ((privring = try_open_mix_file (SECRING, "r+")) == NULL)
    mix_unlock ("secring", privlock);
  else
    {
      /* We're a remailer */
      expmax = time (NULL) + KEYOVERLAP * SECONDSPERDAY;
      while ((pos = next_key (privring)) != -1)
	{
	  if (keyheader (privring, pos, KEY_VERSION, line) == -1)
	    pk++;		/* permanent key, old version */
	  if ((keyheader (privring, pos, KEY_TYPE, line) != -1) &&
	      (streq (line, "sig")))
	    sk++;		/* signature key */
	  else if (keyheader (privring, pos, KEY_EXPIRES, line) == -1)
	    pk++;		/* permanent key */
	  else
	    {
	      sscanf (line, "%lu", &exp);
	      if (exp <= (unsigned long) time (NULL))
		{
		  fseek (privring, pos, SEEK_SET);
		  /* OVERWRITE UNTIL END OF KEY */
		}
	      else
		{
		  expmax = exp;
		  tk++;		/* temporary key */
		}
	    }
	}
      fclose (privring);
      mix_unlock ("secring", privlock);

#ifdef NEW
      if (sk == 0)
	generate_key (KEY_TYPE "sig\n");
#endif
      if (pk == 0)
	generate_key ("");

      for (; tk < CREATEKEYS; tk++)
	{
	  sprintf (line, KEY_VALID "%lu\n" KEY_EXPIRES "%lu\n",
		   expmax - KEYOVERLAP * SECONDSPERDAY,
		   expmax + (KEYVALIDITY - KEYOVERLAP) * SECONDSPERDAY);
	  expmax += (KEYVALIDITY - KEYOVERLAP) * SECONDSPERDAY;
	  generate_key (line);
	}
      /* write our public keys to file */
      write_keyfile ();
    }

  if (keys != NULL)
    read_key_file (keys);

  expire_pub_keys ();
}
Example #26
0
static int
reiserfs_read_data( char *buf, __u32 len )
{
     __u32 blocksize;
     __u32 offset;
     __u32 to_read;
     char *prev_buf = buf;
     errnum = 0;

     DEBUG_F( "reiserfs_read_data: INFO->file->pos=%Lu len=%u, offset=%Lu\n",
	      INFO->file->pos, len, (__u64) IH_KEY_OFFSET(INFO->current_ih) - 1 );


     if ( INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid
	  || IH_KEY_OFFSET( INFO->current_ih ) > INFO->file->pos + 1 )
     {
	  search_stat( INFO->fileinfo.k_dir_id, INFO->fileinfo.k_objectid );
	  goto get_next_key;
     }

     while ( errnum == 0 )
     {
	  if ( INFO->current_ih->ih_key.k_objectid != INFO->fileinfo.k_objectid )
	       break;

	  offset = INFO->file->pos - IH_KEY_OFFSET( INFO->current_ih ) + 1;
	  blocksize = ih_item_len(INFO->current_ih);


	  DEBUG_F( "  loop: INFO->file->pos=%Lu len=%u, offset=%u blocksize=%u\n",
		   INFO->file->pos, len, offset, blocksize );


	  if ( IH_KEY_ISTYPE( INFO->current_ih, TYPE_DIRECT )
	       && offset < blocksize )
	  {
	       to_read = blocksize - offset;
	       if ( to_read > len )
		    to_read = len;

	       memcpy( buf, INFO->current_item + offset, to_read );
	       goto update_buf_len;
	  }
	  else if ( IH_KEY_ISTYPE( INFO->current_ih, TYPE_INDIRECT ) )
	  {
	       blocksize = ( blocksize >> 2 ) << INFO->blocksize_shift;

	       while ( offset < blocksize )
	       {
		    __u32 blocknr = le32_to_cpu(((__u32 *)
						 INFO->current_item)[offset >> INFO->blocksize_shift]);

		    int blk_offset = offset & (INFO->blocksize - 1);

		    to_read = INFO->blocksize - blk_offset;
		    if ( to_read > len )
			 to_read = len;

		    /* Journal is only for meta data.
		       Data blocks can be read directly without using block_read */
		    read_disk_block( INFO->file, blocknr, blk_offset, to_read,
				     buf );

	       update_buf_len:
		    len -= to_read;
		    buf += to_read;
		    offset += to_read;
		    INFO->file->pos += to_read;
		    if ( len == 0 )
			 goto done;
	       }
	  }
     get_next_key:
	  next_key();
     }
Example #27
0
/* preconditions: reiserfs_read_super already executed, therefore
 *   INFO block is valid
 * returns: 0 if error, nonzero iff we were able to find the file successfully
 * postconditions: on a nonzero return, INFO->fileinfo contains the info
 *   of the file we were trying to look up, filepos is 0 and filemax is
 *   the size of the file.
 */
static int
reiserfs_open_file( char *dirname )
{
     struct reiserfs_de_head *de_head;
     char *rest, ch;
     __u32 dir_id, objectid, parent_dir_id = 0, parent_objectid = 0;

     char linkbuf[PATH_MAX];	/* buffer for following symbolic links */
     int link_count = 0;
     int mode;
     errnum = 0;

     dir_id = cpu_to_le32(REISERFS_ROOT_PARENT_OBJECTID);
     objectid = cpu_to_le32(REISERFS_ROOT_OBJECTID);

     while ( 1 )
     {

	  DEBUG_F( "dirname=%s\n", dirname );

	  /* Search for the stat info first. */
	  if ( !search_stat( dir_id, objectid ) )
	       return 0;


	  DEBUG_F( "sd_mode=0%o sd_size=%Lu\n",
		   sd_mode((struct stat_data *) INFO->current_item ),
		   sd_size(INFO->current_ih, INFO->current_item ));


	  mode = sd_mode((struct stat_data *)INFO->current_item);

	  /* If we've got a symbolic link, then chase it. */
	  if ( S_ISLNK( mode ) )
	  {
	       int len = 0;

	       DEBUG_F("link count = %d\n", link_count);
	       DEBUG_SLEEP;
	       if ( ++link_count > MAX_LINK_COUNT )
	       {
		    DEBUG_F("Symlink loop\n");
		    errnum = FILE_ERR_SYMLINK_LOOP;
		    return 0;
	       }

	       /* Get the symlink size. */
	       INFO->file->len = sd_size(INFO->current_ih, INFO->current_item);

	       /* Find out how long our remaining name is. */
	       while ( dirname[len] && !isspace( dirname[len] ) )
		    len++;

	       if ( INFO->file->len + len > sizeof ( linkbuf ) - 1 )
	       {
		    errnum = FILE_ERR_LENGTH;
		    return 0;
	       }

	       /* Copy the remaining name to the end of the symlink data. Note *
		* that DIRNAME and LINKBUF may overlap! */
	       memmove( linkbuf + INFO->file->len, dirname, len + 1 );

	       INFO->fileinfo.k_dir_id = dir_id;
	       INFO->fileinfo.k_objectid = objectid;
	       INFO->file->pos = 0;
	       if ( !next_key()
		    || reiserfs_read_data( linkbuf, INFO->file->len ) != INFO->file->len ) {
		    DEBUG_F("reiserfs_open_file - if !next_key || reiserfs_read_data\n");
		    DEBUG_SLEEP;
		    errnum = FILE_IOERR;
		    return 0;
	       }


	       DEBUG_F( "symlink=%s\n", linkbuf );
	       DEBUG_SLEEP;

	       dirname = linkbuf;
	       if ( *dirname == '/' )
	       {
		    /* It's an absolute link, so look it up in root. */
		    dir_id = cpu_to_le32(REISERFS_ROOT_PARENT_OBJECTID);
		    objectid = cpu_to_le32(REISERFS_ROOT_OBJECTID);
	       }
	       else
	       {
		    /* Relative, so look it up in our parent directory. */
		    dir_id = parent_dir_id;
		    objectid = parent_objectid;
	       }

	       /* Now lookup the new name. */
	       continue;
	  }

	  /* if we have a real file (and we're not just printing *
	   * possibilities), then this is where we want to exit */

	  if ( !*dirname || isspace( *dirname ) )
	  {
	       if ( !S_ISREG( mode ) )
	       {
		    errnum = FILE_ERR_BAD_TYPE;
		    return 0;
	       }

	       INFO->file->pos = 0;
	       INFO->file->len = sd_size(INFO->current_ih, INFO->current_item);

	       INFO->fileinfo.k_dir_id = dir_id;
	       INFO->fileinfo.k_objectid = objectid;
	       return next_key();
	  }

	  /* continue with the file/directory name interpretation */
	  while ( *dirname == '/' )
	       dirname++;
	  if ( !S_ISDIR( mode ) )
	  {
	       errnum = FILE_ERR_NOTDIR;
	       return 0;
	  }
	  for ( rest = dirname; ( ch = *rest ) && !isspace( ch ) && ch != '/';
		rest++ ) ;
	  *rest = 0;

	  while ( 1 )
	  {
	       char *name_end;
	       int num_entries;

	       if ( !next_key() )
		    return 0;

	       if ( INFO->current_ih->ih_key.k_objectid != objectid )
		    break;

	       name_end = INFO->current_item + ih_item_len(INFO->current_ih);
	       de_head = ( struct reiserfs_de_head * ) INFO->current_item;
	       num_entries = ih_entry_count(INFO->current_ih);
	       while ( num_entries > 0 )
	       {
		    char *filename = INFO->current_item + deh_location(de_head);
		    char tmp = *name_end;

		    if( deh_state(de_head) & (1 << DEH_Visible))
		    {
			 int cmp;

			 /* Directory names in ReiserFS are not null * terminated.
			  * We write a temporary 0 behind it. * NOTE: that this
			  * may overwrite the first block in * the tree cache.
			  * That doesn't hurt as long as we * don't call next_key
			  * () in between. */
			 *name_end = 0;
			 cmp = strcmp( dirname, filename );
			 *name_end = tmp;
			 if ( cmp == 0 )
			      goto found;
		    }
		    /* The beginning of this name marks the end of the next name.
		     */
		    name_end = filename;
		    de_head++;
		    num_entries--;
	       }
	  }

	  errnum = FILE_ERR_NOTFOUND;
	  *rest = ch;
	  return 0;

     found:
	  *rest = ch;
	  dirname = rest;

	  parent_dir_id = dir_id;
	  parent_objectid = objectid;
	  dir_id = de_head->deh_dir_id; /* LE */
	  objectid = de_head->deh_objectid; /* LE */
     }
}
Example #28
0
static void text_scan_login(struct connection *conn)
{
	char *key, *value, *data;
	int datasize, idx;
	struct iscsi_login_rsp_hdr *rsp = (struct iscsi_login_rsp_hdr *)&conn->rsp.bhs;

	data = conn->req.data;
	datasize = conn->req.datasize;

	while ((key = next_key(&data, &datasize, &value))) {
		if (!(param_index_by_name(key, login_keys) < 0))
			;
		else if (!strcmp(key, "AuthMethod"))
			;
		else if (!((idx = param_index_by_name(key, session_keys)) < 0)) {
			int err;
			unsigned int val;
			char buf[32];

			if (idx == key_max_xmit_data_length) {
				text_key_add(conn, key, "NotUnderstood");
				continue;
			}
			if (idx == key_max_recv_data_length)
				idx = key_max_xmit_data_length;

			if (param_str_to_val(session_keys, idx, value, &val) < 0) {
				if (conn->session_param[idx].state
				    == KEY_STATE_START) {
					text_key_add_reject(conn, key);
					continue;
				} else {
					rsp->status_class = ISCSI_STATUS_INITIATOR_ERR;
					rsp->status_detail = ISCSI_STATUS_INIT_ERR;
					conn->state = STATE_EXIT;
					goto out;
				}
			}

			err = param_check_val(session_keys, idx, &val);
			err = param_set_val(session_keys, conn->session_param, idx, &val);

			switch (conn->session_param[idx].state) {
			case KEY_STATE_START:
				if (idx == key_max_xmit_data_length)
					break;
				memset(buf, 0, sizeof(buf));
				param_val_to_str(session_keys, idx, val, buf);
				text_key_add(conn, key, buf);
				break;
			case KEY_STATE_REQUEST:
				if (val != conn->session_param[idx].val) {
					rsp->status_class = ISCSI_STATUS_INITIATOR_ERR;
					rsp->status_detail = ISCSI_STATUS_INIT_ERR;
					conn->state = STATE_EXIT;
					log_warning("%s %u %u\n", key,
					val, conn->session_param[idx].val);
					goto out;
				}
				break;
			case KEY_STATE_DONE:
				break;
			}
			conn->session_param[idx].state = KEY_STATE_DONE;
		} else
			text_key_add(conn, key, "NotUnderstood");
	}

out:
	return;
}
Example #29
0
void
write_keyfile (void)
{
  /* read the public keys from secring.mix... */
  FILE *privring, *privlock;
  FILE *keyfile, *keylock, *keyinfo;
  BUFFER *b1, *buff, *header;
#ifdef NEW
  BUFFER *signature;
#endif
  char line[1024], IDstr[80];
  long pos;
  int i, len;
  byte tmpbyte;
  PRIVATE_KEY privkey;
  unsigned char ID[16];
  char abilities[256] = "";
#ifndef USE_RSAREF
  A_PKCS_RSA_PRIVATE_KEY *pkinfo;
#endif

  our_abilities (abilities);

  mix_lock ("secring", &privlock);
  if ((privring = open_mix_file (SECRING, "r+")) == NULL)
    {
      mix_unlock ("secring", privlock);
      return;
    }

  buff = new_buffer ();
#ifdef NEW
  str_to_buffer (buff, begin_signed);
  str_to_buffer (buff, "\n");
#endif
  while ((pos = next_key (privring)) != -1)
    {
      header = new_buffer ();

      for (;;)			/* copy the header and to a buffer */
	{
	  getline (line, sizeof (line), privring);
	  if (!strstr (line, ": "))
	    break;
	  str_to_buffer (header, line);
	}
      if (read_priv_key (privring, &privkey, ID) != 0)
	break;
      encode_ID (IDstr, ID);
      if (memcmp (line, IDstr, 32) != 0)
	{
	  fprintf (errlog, "Error: Private Key IDs do not match!  Bad passphrase?\n");
	  fclose (privring);
	  mix_unlock ("secring", privlock);
	  exit (-1);
	}

      /* write key to buff */
      if (header->length == 0)
	{			/* old format */
	  sprintf (line, "%s %s ", SHORTNAME, REMAILERADDR);
	  str_to_buffer (buff, line);
	  str_to_buffer (buff, IDstr);
	  str_to_buffer (buff, " ");
	  str_to_buffer (buff, mixmaster_protocol);
	  str_to_buffer (buff, VERSION);
	  str_to_buffer (buff, " ");
	  str_to_buffer (buff, abilities);
	  str_to_buffer (buff, "\n\n");
	  str_to_buffer (buff, begin_key);
	  str_to_buffer (buff, "\n");
	}
      else
	{
	  str_to_buffer (buff, begin_key);
	  str_to_buffer (buff, "\n");
	  add_to_buffer (buff, header->message, header->length);
	}
      str_to_buffer (buff, IDstr);
      str_to_buffer (buff, "\n");
      free_buffer (header);

      /* Armor pubkey */
      b1 = new_buffer ();
#ifdef USE_RSAREF
      /* Convert pubkey.bits to two bytes */
      i = privkey.bits;
#else
      B_GetKeyInfo ((POINTER *) & pkinfo, privkey, KI_PKCS_RSAPrivate);
      i = pkinfo->modulus.len * 8;
#endif
      tmpbyte = i & 0xFF;
      add_to_buffer (b1, &tmpbyte, 1);	/* low byte of bits */
      i = i / 256;
      tmpbyte = i & 0xFF;
      add_to_buffer (b1, &tmpbyte, 1);	/* high byte of bits */

#ifdef USE_RSAREF
      add_to_buffer (b1, privkey.modulus, MAX_RSA_MODULUS_LEN);
      add_to_buffer (b1, privkey.publicExponent, MAX_RSA_MODULUS_LEN);
#else
      add_to_buffer (b1, pkinfo->modulus.data, pkinfo->modulus.len);
      if (pkinfo->publicExponent.len < pkinfo->modulus.len)
	add_to_buffer (b1, NULL,
		       pkinfo->modulus.len - pkinfo->publicExponent.len);
      add_to_buffer (b1, pkinfo->publicExponent.data,
		     pkinfo->publicExponent.len);
#endif
      len = b1->length;
      while ((b1->length % 3) != 0)
	str_to_buffer (b1, "X");

      sprintf (line, "%d\n", len);
      str_to_buffer (buff, line);
      armor (b1);
      add_to_buffer (buff, b1->message, b1->length);
      free_buffer (b1);
      str_to_buffer (buff, end_key);
      str_to_buffer (buff, "\n");
    }
  fclose (privring);
  mix_unlock ("secring", privlock);

#ifdef NEW
  str_to_buffer (buff, begin_cfg);
  sprintf (line, "\n%s%s\n", KEY_VERSION, VERSION);
  str_to_buffer (buff, line);
  sprintf (line, "%s%s\n", CFG_REMAILER, SHORTNAME);
  str_to_buffer (buff, line);
  sprintf (line, "%s%s\n", CFG_ADDRESS, REMAILERADDR);
  str_to_buffer (buff, line);
  sprintf (line, "%s%s\n", CFG_ABILITIES, abilities);
  str_to_buffer (buff, line);
  sprintf (line, "%s%lu\n", CFG_DATE, (unsigned long) time (NULL));
  str_to_buffer (buff, line);
  str_to_buffer (buff, end_cfg);

  signature = new_buffer ();
  create_sig (buff, signature);
  armor (signature);
  str_to_buffer (buff, "\n");
  str_to_buffer (buff, begin_signature);
  str_to_buffer (buff, "\n");
  add_to_buffer (buff, signature->message, signature->length);
  str_to_buffer (buff, end_signature);
#endif

  mix_lock ("key", &keylock);
  if ((keyinfo = open_mix_file (KEYINFO, "r")) == NULL ||
      (keyfile = open_mix_file (KEYFILE, "w")) == NULL)
    {
      mix_unlock ("key", keylock);
      return;
    }
  while (getline (line, sizeof (line), keyinfo) != NULL)
    fprintf (keyfile, "%s\n", line);
  fclose (keyinfo);
  write_buffer (buff, keyfile);
  fclose (keyfile);
  mix_unlock ("key", keylock);
  free_buffer (buff);
}
Example #30
0
// Japanese leaf state calculation from capture data.
// We could store territory for the UI, it takes too much space.
void calculate_leaves(solution *sol) {
    state s_;
    state *s = &s_;
    size_t key;
    size_t zero_layer = abs(sol->base_state->ko_threats);
    state new_s_;
    state *new_s = &new_s_;
    key = sol->d->min_key;
    size_t num_states = num_keys(sol->d);
    for (size_t i = 0; i < num_states; i++) {
        assert(from_key_s(sol, s, key, zero_layer));

        *new_s = *s;
        node_value v = negamax_node(sol, s, key, zero_layer, 0);
        node_value v_b = sol->base_nodes[zero_layer][i];
        assert(equal(v, v_b));
        endstate(sol, new_s, v, 0, 1);

        // Use a flood of life so that partially dead nakade won't give extra points.
        // Note while this won't mark dead groups as alive, it can treat living nakade stones as dead.
        stones_t player_alive = flood(new_s->player, s->player);
        stones_t opponent_alive = flood(new_s->opponent, s->opponent);

        int score;

        // First check if a target is not alive.
        stones_t player_target = s->player & s->target;
        stones_t opponent_target = s->opponent & s->target;
        if (opponent_target & ~opponent_alive) {
            // Make sure that both aren't dead.
            assert(!(player_target & ~player_alive));
            score = TARGET_SCORE;
        }
        else if (player_target & ~player_alive) {
            score = -TARGET_SCORE;
        }
        else {
            stones_t player_territory = 0;
            stones_t opponent_territory = 0;
            stones_t player_region_space = s->playing_area & ~player_alive;
            stones_t opponent_region_space = s->playing_area & ~opponent_alive;
            for (int j = 0; j < STATE_SIZE; j++) {
                stones_t p = 1ULL << j;
                stones_t region = flood(p, player_region_space);
                player_region_space ^= region;
                if (!(region & opponent_alive)) {
                    player_territory |= region;
                }
                region = flood(p, opponent_region_space);
                opponent_region_space ^= region;
                if (!(region & player_alive)) {
                    opponent_territory |= region;
                }
            }
            // Subtract friendly stones on the board from territory.
            player_territory &= ~s->player;
            opponent_territory &= ~s->opponent;
            score = popcount(player_territory) + popcount(player_territory & s->opponent) - popcount(opponent_territory) - popcount(opponent_territory & s->player);
        }

        sol->leaf_nodes[i] = score;

        key = next_key(sol->d, key);
    }
}