func translateCardDecomposition(n int, typ constraints.OneTranslationType) (clauses sat.ClauseSet) { p := sat.Pred("v") for i := 0; i < n; i++ { for j := 0; j < n; j++ { lits := make([]sat.Literal, n) for k := 0; k < n; k++ { lits[k] = sat.Literal{true, sat.NewAtomP3(p, i, j, k)} } //clauses.AddTaggedClause("AtLeast", lits...) clauses.AddClauseSet(constraints.TranslateExactlyOne(typ, "ex1Value", lits).Clauses) } } for k := 0; k < n; k++ { for i := 0; i < n; i++ { lits := make([]sat.Literal, n) for j := 0; j < n; j++ { lits[j] = sat.Literal{true, sat.NewAtomP3(p, i, j, k)} } // in each row each value at most one clauses.AddClauseSet(constraints.TranslateExactlyOne(typ, "ex1Row", lits).Clauses) } } for k := 0; k < n; k++ { for j := 0; j < n; j++ { lits := make([]sat.Literal, n) for i := 0; i < n; i++ { lits[i] = sat.Literal{true, sat.NewAtomP3(p, i, j, k)} } // in each column each value at most one clauses.AddClauseSet(constraints.TranslateExactlyOne(typ, "ex1Column", lits).Clauses) } } return }
func translateInstance(g QGC) (clauses sat.ClauseSet) { p := sat.Pred("v") for i, r := range g { for j, k := range r { if k >= 0 { l1 := sat.Literal{true, sat.NewAtomP3(p, i, j, k)} clauses.AddTaggedClause("Instance", l1) } } } return }
// 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) }