Ejemplo n.º 1
0
// Translate monotone MDDs to SAT
// Together with AMO translation
func convertMDD2Clauses(store mdd.IntervalMddStore, pb *Threshold) (clauses sat.ClauseSet) {

	pred := sat.Pred("mdd" + strconv.Itoa(pb.Id))

	top_lit := sat.Literal{true, sat.NewAtomP1(pred, store.Top)}
	clauses.AddTaggedClause("Top", top_lit)
	for _, n := range store.Nodes {
		v_id, l, vds := store.ClauseIds(*n)
		if !n.IsZero() && !n.IsOne() {

			v_lit := sat.Literal{false, sat.NewAtomP1(pred, v_id)}
			last_id := -1
			for i, vd_id := range vds {
				if last_id != vd_id {
					vd_lit := sat.Literal{true, sat.NewAtomP1(pred, vd_id)}
					if i > 0 {
						literal := pb.Entries[len(pb.Entries)-l+i-1].Literal
						clauses.AddTaggedClause("1B", v_lit, sat.Neg(literal), vd_lit)
					} else {
						clauses.AddTaggedClause("0B", v_lit, vd_lit)
					}
				}
				last_id = vd_id
			}
		} else if n.IsZero() {
			v_lit := sat.Literal{false, sat.NewAtomP1(pred, v_id)}
			clauses.AddTaggedClause("False", v_lit)
		} else if n.IsOne() {
			v_lit := sat.Literal{true, sat.NewAtomP1(pred, v_id)}
			clauses.AddTaggedClause("True", v_lit)
		}

	}

	return
}
Ejemplo n.º 2
0
// Chains is a set of chains in order of the PB
// Chain: there are clauses  xi <-xi+1 <- xi+2 ... <- xi+k, and xi .. xi+k are in order of PB
// assumption: chains are subsets of literals of PB and in their order
func CreateMDDChain(store *mdd.IntervalMddStore, K int64, entries []Entry, chains Chains) (int, int64, int64, error) {

	l := len(entries) ///level

	if store.MaxNodes < len(store.Nodes) {
		return 0, 0, 0, errors.New("mdd max nodes reached")
	}

	//chain.Print()
	//fmt.Println(l, K, entries)

	if id, wmin_cache, wmax_cache := store.GetByWeight(l, K); id != -1 {

		//	fmt.Println("exists", l, K, "[", wmin, wmax, "]")

		return id, wmin_cache, wmax_cache, nil

	} else {
		//domain of variable [0,1], extend to [0..n] soon (MDDs)
		// entry of variable domain, atom: Dom: 2

		var n mdd.IntervalNode
		var err error

		//glob.D(entries, chains)

		glob.A(len(chains) == 0 || len(chains[0]) > 0, "if exists, then chain must contain at least 1 element")
		if len(chains) > 0 && chains[0][0] == entries[0].Literal { //chain mode
			chain := chains[0]
			var jumpEntries []Entry
			if len(entries) <= len(chain) { // can this happen if entries and chains are perfectly aligned?
				jumpEntries = []Entry{}
			} else {
				jumpEntries = entries[len(chain):]
			}
			// iterate over the chain
			n.Level = l
			n.Children = make([]int, len(chain)+1)

			n.Children[0], n.Wmin, n.Wmax, err = CreateMDDChain(store, K, jumpEntries, chains[1:])

			if err != nil {
				return 0, 0, 0, err
			}

			acc := int64(0)

			//			fmt.Printf("entries:%v  chain: %v", entries, chain)
			for i, _ := range chain {

				glob.A(len(chain) <= len(entries), "chain and PB are not aligned!!!! ")
				glob.A(chain[i] == entries[i].Literal, "chain and PB are not aligned!!!! ")

				var wmin2, wmax2 int64
				acc += entries[i].Weight
				n.Children[i+1], wmin2, wmax2, err = CreateMDDChain(store, K-acc, jumpEntries, chains[1:])
				n.Wmin = maxx(n.Wmin, wmin2+acc)
				n.Wmax = min(n.Wmax, wmax2+acc)

				if err != nil {
					return 0, 0, 0, err
				}

			}

		} else { //usual mode or for int-variables
			dom := 2
			n.Level = l
			n.Children = make([]int, dom)
			n.Wmin = math.MinInt64
			n.Wmax = math.MaxInt64

			var err error
			for i := int64(0); i < int64(dom); i++ {
				var wmin2, wmax2 int64

				n.Children[i], wmin2, wmax2, err = CreateMDDChain(store, K-i*entries[0].Weight, entries[1:], chains)

				n.Wmin = maxx(n.Wmin, wmin2+i*entries[0].Weight)
				n.Wmax = min(n.Wmax, wmax2+i*entries[0].Weight)

				if err != nil {
					return 0, 0, 0, err
				}
			}
		}

		return store.Insert(n), n.Wmin, n.Wmax, nil
	}
}