// ---------------------------------------------------------------------------- // // 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< 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); } }