void mk_transition(int row, int col, int i0, int j, int pos) { Car car0 = cars[pos]; List <BoolExpr> body = new List <BoolExpr>(); body.Add(mk_state(car0, i0)); for (int index = 0; index < num_cars; ++index) { Car car = cars[index]; if (car0 != car) { if (car.is_vertical && car.base_pos == col) { for (int i = 0; i < dimension; ++i) { if (i <= row && row < i + car.length && i + car.length <= dimension) { body.Add(ctx.MkNot(ctx.MkEq(bound(index), num(i)))); } } } if (car.base_pos == row && !car.is_vertical) { for (int i = 0; i < dimension; ++i) { if (i <= col && col < i + car.length && i + car.length <= dimension) { body.Add(ctx.MkNot(ctx.MkEq(bound(index), num(i)))); } } } } } Symbol s = ctx.MkSymbol(string.Format("{0} {1}->{2}", car0.color, i0, j)); fp.AddRule(ctx.MkImplies(ctx.MkAnd(body.ToArray()), mk_state(car0, j)), s); }
public void Run() { using (Context ctx = new Context()) { this.ctx = ctx; ctx.UpdateParamValue("DL_GENERATE_EXPLANATIONS", "true"); red_car = new Car(false, 2, 2, 3, "red"); cars = new Car[] { new Car(true, 0, 3, 0, "yellow"), new Car(false, 3, 3, 0, "blue"), new Car(false, 5, 2, 0, "brown"), new Car(false, 0, 2, 1, "lgreen"), new Car(true, 1, 2, 1, "light blue"), new Car(true, 2, 2, 1, "pink"), new Car(true, 2, 2, 4, "dark green"), red_car, new Car(true, 3, 2, 3, "purple"), new Car(false, 5, 2, 3, "light yellow"), new Car(true, 4, 2, 0, "orange"), new Car(false, 4, 2, 4, "black"), new Car(true, 5, 3, 1, "light purple") }; this.num_cars = cars.Length; this.B = ctx.MkBoolSort(); this.bv3 = ctx.MkBitVecSort(3); List <Sort> domain = new List <Sort>(); foreach (var c in cars) { domain.Add(bv3); } this.state = ctx.MkFuncDecl("state", domain.ToArray(), B); this.fp = ctx.MkFixedpoint(); this.fp.RegisterRelation(state); // Initial state: Expr[] args = new Expr[num_cars]; for (int i = 0; i < num_cars; ++i) { args[i] = num(cars[i].start); } fp.AddRule((BoolExpr)state[args]); // Transitions: for (int pos = 0; pos < num_cars; ++pos) { Car car = cars[pos]; for (int i = 0; i < dimension; ++i) { if (car.is_vertical) { move_down(i, pos, car); move_up(i, pos, car); } else { move_left(i, pos, car); move_right(i, pos, car); } } } // Print the current context: Console.WriteLine("{0}", fp); // Prepare the query: for (int i = 0; i < num_cars; ++i) { args[i] = (cars[i] == red_car) ? num(4) : bound(i); } BoolExpr goal = (BoolExpr)state[args]; fp.Query(goal); // Extract a path: get_instructions(fp.GetAnswer()); } }