Ejemplo n.º 1
0
// 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))

}
Ejemplo n.º 2
0
// 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)
}