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