func TestWhichClauses(t *testing.T) { //sizes := []int{100,112,128,144,160,176} //sizes := []int{500, 750, 1000} sizes := []int{5, 10, 15} //sizes := []int{} typs := []sorters.SortingNetworkType{sorters.Bubble, sorters.Bitonic, sorters.OddEven, sorters.Pairwise} //typs := []sorters.SortingNetworkType{Bitonic, OddEven, Pairwise} //typs := []sorters.SortingNetworkType{sorters.OddEven, sorters.Pairwise} //typs := []sorters.SortingNetworkType{sorters.Pairwise} whichT := []int{1, 2, 3, 4} lt := Pred("AtMost") gt := Pred("AtLeast") for _, size := range sizes { for _, typ := range typs { for _, wh := range whichT { //k := int(0.05 * float64(size)) k := size / 4 //k := size - size/4 sorter1 := sorters.CreateCardinalityNetwork(size, k, sorters.AtMost, typ) sorter2 := sorters.CreateCardinalityNetwork(size, k+1, sorters.AtLeast, typ) sorter1.RemoveOutput() sorter2.RemoveOutput() var which1 [8]bool var which2 [8]bool switch wh { case 1: which1 = [8]bool{false, false, false, true, true, true, false, false} which2 = [8]bool{false, true, true, false, false, false, true, false} case 2: which1 = [8]bool{false, false, false, true, true, true, false, true} which2 = [8]bool{false, true, true, false, false, false, true, true} case 3: which1 = [8]bool{false, true, true, true, true, true, true, false} which2 = [8]bool{false, true, true, true, true, true, true, false} case 4: which1 = [8]bool{false, true, true, true, true, true, true, true} which2 = [8]bool{false, true, true, true, true, true, true, true} } input := make([]Literal, size) for i, _ := range input { input[i] = Literal{true, NewAtomP1(Pred("Input"), i)} } clauses := CreateEncoding(input, which1, []Literal{}, "lt", lt, sorter1) clauses.AddClauseSet(CreateEncoding(input, which2, []Literal{}, "gt", gt, sorter2)) g := IdGenerator(size * size) //g.GenerateIds(clauses) g.Filename = os.TempDir() + "/" + strconv.Itoa(size) + "_" + strconv.Itoa(k) + "_" + typ.String() + "_" + strconv.Itoa(wh) + ".cnf" g.PrintDIMACS(clauses) } } } }
func translateToSAT(vc VertexCover) (clauses sat.ClauseSet) { p := sat.Pred("vc") //at least constraint for each edge s := "at least one" for _, e := range vc.Edges { l1 := sat.Literal{true, sat.Atom{p, e.a, 0}} l2 := sat.Literal{true, sat.Atom{p, e.b, 0}} clauses.AddClause(s, l1, l2) } //global counter sorter := sorters.CreateCardinalityNetwork(vc.NVertex, vc.Size, sorters.AtMost, sorters.Pairwise) sorter.RemoveOutput() litIn := make([]sat.Literal, vc.NVertex) for i, _ := range litIn { litIn[i] = sat.Literal{true, sat.Atom{p, i + 1, 0}} } which := [8]bool{false, false, false, true, true, true, false, false} pred := sat.Pred("aux") clauses.AddClauseSet(sat.CreateEncoding(litIn, which, []sat.Literal{}, "atMost", pred, sorter)) return }
// CreateCardinality takes set of literals and creates a sorting network func (pb *Threshold) CreateCardinality() { for _, x := range pb.Entries { glob.A(x.Weight == 1, "Prerequisite for this translation") } literals := pb.Literals() sx := strconv.Itoa(int(pb.K)) + "\\" + strconv.Itoa(len(literals)) var s string var sorterEqTyp sorters.EquationType var w int // which type of clauses switch pb.Typ { case LE: w = 0 sorterEqTyp = sorters.AtMost s = pb.IdS() + "pb<SN" + sx case GE: w = 3 sorterEqTyp = sorters.AtLeast s = pb.IdS() + "pb>SN" + sx case EQ: w = 3 s = pb.IdS() + "pb=SN" + sx sorterEqTyp = sorters.Equal default: panic("Not supported") } sorter := sorters.CreateCardinalityNetwork(len(literals), int(pb.K), sorterEqTyp, sorters.Pairwise) sorter.RemoveOutput() pred := sat.Pred("SN-" + pb.IdS()) output := make([]sat.Literal, 0) pb.Clauses.AddClauseSet(CreateEncoding(literals, sorters.WhichCls(w), output, s, pred, sorter)) }
// returns the encoding of this PB // adds to internal clauses func (pb *Threshold) RewriteSameWeights() { // put following two lines in the code itself // go to the end of chains // reorder PB after this descending posAfterChains := pb.PosAfterChains() entries := pb.Entries[posAfterChains:] //glob.D(pb) es := make([]Entry, 0, len(entries)) rest := make([]Entry, 0, len(entries)) newEntries := make([]Entry, len(entries)) last := int64(-1) rewrite := 0 //number of rewrite chains pos := 0 // current position in newEntries pred := sat.Pred("re-aux") for i, x := range entries { if last == x.Weight { es = append(es, entries[i]) } else { if len(es) >= *glob.Len_rewrite_same_flag { rewrite++ var most int if pb.Typ == OPT { if *glob.Opt_bound_flag >= 0 { most = int(min(int64(len(es)), int64(math.Floor(float64(*glob.Opt_bound_flag)/float64(last))))) } else { most = len(es) } } else { most = int(min(int64(len(es)), int64(math.Floor(float64(pb.K)/float64(last))))) } output := make(Lits, most) input := make(Lits, len(es)) for j, _ := range input { if j < most { output[j] = sat.Literal{true, sat.NewAtomP3(pred, pb.Id, rewrite, j)} newEntries[pos] = Entry{output[j], es[j].Weight} pos++ } input[j] = es[j].Literal } sorter := sorters.CreateCardinalityNetwork(len(input), most, sorters.AtMost, sorters.Pairwise) sn_aux := sat.Pred("SN-" + pb.IdS() + "-" + strconv.Itoa(rewrite)) cls := CreateEncoding(input, sorters.WhichCls(2), output, pb.IdS()+"re-SN", sn_aux, sorter) //glob.D(pb.Id, "SN", len(input), most, cls.Size()) pb.Clauses.AddClauseSet(cls) pb.Chains = append(pb.Chains, Chain(output)) } else { rest = append(rest, es...) //glob.D("dont rewrite this", rest) } es = []Entry{entries[i]} } last = x.Weight } if len(es) >= *glob.Len_rewrite_same_flag { rewrite++ var most int if pb.Typ == OPT { if *glob.Opt_bound_flag != math.MaxInt64 { // glob.D(pb.Id, "Check", *glob.Opt_bound_flag+pb.Offset) most = int(min(int64(len(es)), int64(math.Floor(float64(*glob.Opt_bound_flag+pb.Offset)/float64(last))))) } else { most = len(es) } } else { most = int(min(int64(len(es)), int64(math.Floor(float64(pb.K)/float64(last))))) } //glob.D("most", most, "len(es)", len(es), "K", pb.K, "last", last) sn_aux := sat.Pred("SN-" + pb.IdS() + "-" + strconv.Itoa(rewrite)) output := make(Lits, most) input := make(Lits, len(es)) for j, _ := range input { if j < most { output[j] = sat.Literal{true, sat.NewAtomP3(pred, pb.Id, rewrite, j)} newEntries[pos] = Entry{output[j], es[j].Weight} pos++ } input[j] = es[j].Literal } sorter := sorters.CreateCardinalityNetwork(len(input), most, sorters.AtMost, sorters.Pairwise) cls := CreateEncoding(input, sorters.WhichCls(2), output, pb.IdS()+"re-SN", sn_aux, sorter) //glob.D(pb.Id, "SN", len(input), most, cls.Size()) pb.Clauses.AddClauseSet(cls) pb.Chains = append(pb.Chains, Chain(output)) } else { rest = append(rest, es...) } for _, x := range rest { newEntries[pos] = x pos++ } //glob.A(pos == len(newEntries), "Not enough entries copied!!") pb.Entries = pb.Entries[:posAfterChains+pos] copy(pb.Entries[posAfterChains:], newEntries) //glob.D(pb) //glob.D(pb.Chains) }