singrdk/base/Applications/Benchmarks/sharpSAT/basic_classes.cs

329 lines
10 KiB
C#

///////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
///////////////////////////////////////////////////////////////////////////////
using System;
using System.Collections;
using System.Diagnostics;
//using Microsoft.Zap;
namespace SharpSAT
{
public class Variable : SATCommon
{
//public bool branchable = true;
//public bool reasoning = true;
private ushort flags = 0;
public ushort gflag = 0;
public NodeType type = NodeType.UNKNOWN;
public IntVector outputs = new IntVector(2);
public int left = INVALID;
public int right = INVALID;
public int canonical = INVALID;
public int ref_count = 0;
public short lits_count_0= 0;
public short lits_count_1= 0;
public int uid = 0;
public short score_0 = 0;
public short score_1 = 0;
public int asgn_pos = -1;
public int ordered_pos = 0;
public short varValue = UNKNOWN;
public Antecedent antecedent= -1;
public int dlevel = -1;
public void set_gid (int i) { gflag |= (ushort) (1<<(i-1)); }
public void clear_gid(int i) { gflag &= (ushort) ~(1<<(i-1)); }
public void clear_all_gid() { gflag = 0; }
public bool gid (int i) { return (( gflag & (ushort) (1<<(i-1))) != 0); }
public void clear_all_flag() { flags = 0; }
public void set_flag(int idx) { flags |= (ushort) (1 << idx); }
public void clear_flag(int idx) { flags &= (ushort) (~(1<<idx));}
public bool flag(int idx) { return (flags & (ushort) (1<< idx)) != 0; }
public int score() { return (score_0 > score_1? score_0 : score_1); }
public int lits_count() { return lits_count_0 + lits_count_1; }
public bool is_pi() { return type == NodeType.PI; }
public bool is_gate() { return (type == NodeType.AND || type == NodeType.XOR); }
public int output(int i) { return outputs[i];}
public int input(int k) { return (k==0 ? left: right); }
}
public class Clause : SATCommon
{
public ClType type = ClType.UNKNOWN; //indicates the clause type
public ushort gflag = 0;
public int uid = 0;
public int[] literals = null;
public int activity = 0;
public void init (ClType tp, int [] lits, ushort gflg, int id)
{
type = tp;
literals = new int[lits.Length];
Array.Copy(lits, 0, literals, 0, lits.Length);
gflag = gflg;
uid = id;
activity = 0;
}
public bool gid (int i)
{
sharp_assert (i>=1 && i<= WORD_WIDTH);
return (( gflag & (ushort)(1<<(i-1))) != 0);
}
public void set_gid (int i)
{
sharp_assert (i>=1 && i<= WORD_WIDTH);
gflag |= (ushort)(1<<(i-1));
}
public void clear_gid(int i)
{
sharp_assert (i>=1 && i<= WORD_WIDTH);
gflag &= (ushort)~(1<<(i-1));
}
public int num_lits { get {return literals.Length; } }
public int literal (int n)
{
return literals[n];
}
}
public struct Antecedent
{
private int anteVal;
public static implicit operator Antecedent( int v ) { return new Antecedent(v); }
public static implicit operator int (Antecedent an) { return an.anteVal; }
public Antecedent (int v) { anteVal = v; }
public Antecedent (ImpType tp, int index)
{
anteVal = (index << 3) + (int) tp;
}
public ImpType type
{
get { return (ImpType) (anteVal & 0x7); }
set
{
uint a = (uint) anteVal & (~(uint) 0x7);
uint b = (uint) value;
anteVal = (int) (a | b);
//anteVal = (((uint)anteVal) & (~(uint)0x7)) | (uint) value;
}
}
public int index
{
get { return (anteVal >> 3); }
set { anteVal = ((anteVal & 7) | (value << 3)); }
}
}
public struct Implication
{
public int lit;
public Antecedent ante;
}
public class NodeHashMap : SATCommon
{
private const int XOR_MARK = (1 << 30);
private MyHashtable hash_table = new MyHashtable();
private class NodeHashMapKey
{
public int left;
public int right;
public NodeHashMapKey(int l, int r)
{
left = l;
right = r;
}
public override int GetHashCode()
{
long hashcode = left;
hashcode <<= 16;
hashcode ^= right;
int lsig = (int)(hashcode & 0xffffffff);
int msig = (int)(hashcode >> 32);
return lsig ^ msig;
}
public override bool Equals(object obj)
{
NodeHashMapKey other = obj as NodeHashMapKey;
if(other == null) return false;
return other.left == left && other.right == right;
}
}
public int lookup (NodeType op, int i1, int i2)
{
sharp_assert (op == NodeType.AND || op == NodeType.XOR);
//1. left input always has smaller index than right
if (i1 > i2)
{
int temp = i1;
i1 = i2;
i2 = temp;
}
//2. For XOR gate, always require both inputs not negated
bool do_NEGATE = false;
if (op == NodeType.XOR)
{
if (IS_NEGATED(i1))
{
i1 = NEGATE (i1);
do_NEGATE = !do_NEGATE;
}
if (IS_NEGATED(i2))
{
i2 = NEGATE(i2);
do_NEGATE = !do_NEGATE;
}
}
//3. put special mark on the XOR node
int l, r;
l = i1;
r = i2;
if (op == NodeType.XOR)
l += XOR_MARK;
//4. Lookup
NodeHashMapKey key = new NodeHashMapKey(l, r);
// ulong key = ((ulong)l << 32) + (ulong) r;
object item = hash_table[key];
if (item == null)
return INVALID;
int o = (int) item;
if (do_NEGATE)
o = NEGATE(o);
return o;
}
public void insert ( int n, NodeType op, int i1, int i2)
{
sharp_assert (op == NodeType.AND || op == NodeType.XOR);
sharp_assert (i1 < i2);
sharp_assert (! ( (op == NodeType.XOR) &&
( IS_NEGATED(i1) || IS_NEGATED(i2) )));
sharp_assert (!IS_NEGATED(n));
int l, r;
l = i1;
r = i2;
if (op == NodeType.XOR)
l += XOR_MARK;
NodeHashMapKey key = new NodeHashMapKey(l, r);
// ulong key = ((ulong)l << 32) + (ulong) r;
sharp_assert ( !hash_table.Contains(key));
hash_table[key] = n;
}
public void remove ( int n, NodeType op, int i1, int i2)
{
sharp_assert (op == NodeType.AND || op == NodeType.XOR);
sharp_assert (i1 < i2);
sharp_assert (! ( (op == NodeType.XOR) &&
( IS_NEGATED(i1) || IS_NEGATED(i2) )));
sharp_assert ( ! IS_NEGATED(n) );
//put special mark on the XOR node
int l, r;
l = i1;
r = i2;
if (op == NodeType.XOR)
l += XOR_MARK;
NodeHashMapKey key = new NodeHashMapKey(l, r);
// ulong key = ((ulong)l << 32) + (ulong) r;
sharp_assert ( (int)hash_table[key] == n);
hash_table.Remove(key);
}
}
class FreeList
{
VarVector variables;
IntVector free_list;
int delete_count;
const double compact_ratio = 0.5;
public FreeList (VarVector vars)
{
free_list = new IntVector(16);
variables = vars;
}
public void add (IntVector new_frees)
{
for (int i=0; i< new_frees.size(); ++i)
free_list.push_back(new_frees[i]);
free_list.sort();
}
public void delete_index (int idx)
{
delete_count ++;
if ((double)delete_count / (double)free_list.size() > compact_ratio)
{
IntVector temp = new IntVector(16);
for (int i=0; i< free_list.size(); ++i)
{
if (idx == i) //just deleted, so won't be in free_list anymore
continue;
if (variables[free_list[i]] == null ||
variables[free_list[i]].type == NodeType.FREE )
temp.push_back(free_list[i]);
}
free_list = temp;
}
}
public int find_greater_than (int v)
{
int idx = free_list.binary_search (v);
if (idx < 0)
idx = ~ idx;
else
idx ++;
for (int i=idx; i < free_list.size(); ++i)
{
if (variables[free_list[i]] == null ||
variables[free_list[i]].type == NodeType.FREE )
{
int r = free_list[i];
delete_index(i);
return r;
}
}
return -1;
}
}
public class UnsatCore
{
public int [] core_clauses;
public int [] core_nodes;
}
public class MyHashtable : Hashtable {}
public interface SATHook
{
void OnBCP();
void OnBacktrack(int blevel);
void OnCaseSplit(int svar);
}
}