Skip to content

Conversation

@marfvr
Copy link
Member

@marfvr marfvr commented Oct 2, 2023

Proposed changes

Continuation of #262 from the new tip of the project (i.e. after #264).

@marfvr
Copy link
Member Author

marfvr commented Oct 2, 2023

To reproduce the problem in 25bacb0:

this is the domain.pddl file:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 4 Op-blocks world
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define (domain blocks-domain)
  (:requirements :disjunctive-preconditions :strips :typing)
  (:types block)
  (:predicates
	       (ontable ?x - block)
	       (on ?x ?y - block)
	       (clear ?x - block)
	       (emptyhand)
	       (holding ?x - block)
	       )

  (:action pick-up
	     :parameters (?x - block)
	     :precondition (and (clear ?x) (ontable ?x) (emptyhand))
	     :effect
	     (and (not (ontable ?x))
		   (not (clear ?x))
		   (not (emptyhand))
		   (holding ?x)))

  (:action put-down
	     :parameters (?x - block)
	     :precondition (holding ?x)
	     :effect
	     (and (not (holding ?x))
		   (clear ?x)
		   (emptyhand)
		   (ontable ?x)))
  (:action stack
	     :parameters (?x ?y - block)
	     :precondition (and (holding ?x) (clear ?y))
	     :effect
	     (and (not (holding ?x))
		   (not (clear ?y))
		   (clear ?x)
		   (emptyhand)
		   (on ?x ?y)))
  (:action unstack
	     :parameters (?x ?y - block)
	     :precondition (and (on ?x ?y) (clear ?x) (emptyhand))
	     :effect
	     (and (holding ?x)
		   (clear ?y)
		   (not (clear ?x))
		   (not (emptyhand))
		   (not (on ?x ?y)))))

This is the problem file:

(define (problem bw_10)
  (:domain blocks-domain)
  (:objects b1 b2 b3 - block)
  (:init (emptyhand) (ontable b1) (ontable b2) (ontable b3) (clear b1) (clear b2) (clear b3))
  (:goal (and (emptyhand)))
)

This is the goal formula:

O(on_b1_b2 & Y(O(on_b2_b3)))

Run:

plan4past -d domain.pddl -p p3.pddl --goal-inline "O(on_b1_b2 & Y(O(on_b2_b3)))"

This produces: new-domain.pddl:

(define (domain blocks-domain)
    (:requirements :conditional-effects :derived-predicates :disjunctive-preconditions :negative-preconditions :strips :typing)
    (:types block)
    (:predicates (Y-quoted_0) (Y-quoted_2) (clear ?x - block)  (emptyhand) (holding ?x - block)  (on ?x - block ?y - block)  (ontable ?x - block)  (quoted_1) (val-quoted_0) (val-quoted_1) (val-quoted_2) (val-quoted_3) (val-quoted_4) (val-quoted_5))
    (:derived (val-quoted_0) (or (val-quoted_3) (Y-quoted_0)))
     (:derived (val-quoted_1) (quoted_1))
     (:derived (val-quoted_2) (or (val-quoted_5) (Y-quoted_2)))
     (:derived (val-quoted_3) (and (val-quoted_4) (val-quoted_1)))
     (:derived (val-quoted_4) (on b1 b2))
     (:derived (val-quoted_5) (on b2 b3))
    (:action pick-up
        :parameters (?x - block)
        :precondition (and (clear ?x) (ontable ?x) (emptyhand))
        :effect (and (not (ontable ?x)) (not (clear ?x)) (not (emptyhand)) (holding ?x) (when (not (val-quoted_2)) (not (Y-quoted_2))) (when (not (val-quoted_0)) (not (Y-quoted_0))) (when (val-quoted_1) (quoted_1)) (when (val-quoted_0) (Y-quoted_0)) (when (val-quoted_2) (Y-quoted_2)) (when (not (val-quoted_1)) (not (quoted_1))))
    )
     (:action put-down
        :parameters (?x - block)
        :precondition (holding ?x)
        :effect (and (not (holding ?x)) (clear ?x) (emptyhand) (ontable ?x) (when (not (val-quoted_2)) (not (Y-quoted_2))) (when (not (val-quoted_0)) (not (Y-quoted_0))) (when (val-quoted_1) (quoted_1)) (when (val-quoted_0) (Y-quoted_0)) (when (val-quoted_2) (Y-quoted_2)) (when (not (val-quoted_1)) (not (quoted_1))))
    )
     (:action stack
        :parameters (?x - block ?y - block)
        :precondition (and (holding ?x) (clear ?y))
        :effect (and (not (holding ?x)) (not (clear ?y)) (clear ?x) (emptyhand) (on ?x ?y) (when (not (val-quoted_2)) (not (Y-quoted_2))) (when (not (val-quoted_0)) (not (Y-quoted_0))) (when (val-quoted_1) (quoted_1)) (when (val-quoted_0) (Y-quoted_0)) (when (val-quoted_2) (Y-quoted_2)) (when (not (val-quoted_1)) (not (quoted_1))))
    )
     (:action unstack
        :parameters (?x - block ?y - block)
        :precondition (and (on ?x ?y) (clear ?x) (emptyhand))
        :effect (and (holding ?x) (clear ?y) (not (clear ?x)) (not (emptyhand)) (not (on ?x ?y)) (when (not (val-quoted_2)) (not (Y-quoted_2))) (when (not (val-quoted_0)) (not (Y-quoted_0))) (when (val-quoted_1) (quoted_1)) (when (val-quoted_0) (Y-quoted_0)) (when (val-quoted_2) (Y-quoted_2)) (when (not (val-quoted_1)) (not (quoted_1))))
    )
)

and problem:

(define (problem bw_10)
    (:domain blocks-domain)
    (:objects b1 - block b2 - block b3 - block)
    (:init (clear b1) (clear b2) (clear b3) (emptyhand) (ontable b1) (ontable b2) (ontable b3))
    (:goal (val-quoted_0))
)

The planner cannot find the plan:

planutils run downward new-domain.pddl new-problem.pddl "--search astar(ff())" 

However, when running it for the old compilation, it works: new-domain.pddl:

(define (domain blocks-domain)
    (:requirements :conditional-effects :derived-predicates :disjunctive-preconditions :negative-preconditions :strips :typing)
    (:types block)
    (:predicates (Y-Oon_b1_b2-and-YOon_b2_b3) (Y-Oon_b2_b3) (YOon_b2_b3) (clear ?x - block)  (emptyhand) (holding ?x - block)  (on ?x - block ?y - block)  (ontable ?x - block)  (val-Oon_b1_b2-and-YOon_b2_b3) (val-Oon_b2_b3) (val-YOon_b2_b3) (val-on_b1_b2) (val-on_b1_b2-and-YOon_b2_b3) (val-on_b2_b3))
    (:derived (val-Oon_b1_b2-and-YOon_b2_b3) (or (val-on_b1_b2-and-YOon_b2_b3) (Y-Oon_b1_b2-and-YOon_b2_b3)))
     (:derived (val-Oon_b2_b3) (or (val-on_b2_b3) (Y-Oon_b2_b3)))
     (:derived (val-YOon_b2_b3) (YOon_b2_b3))
     (:derived (val-on_b1_b2) (on b1 b2))
     (:derived (val-on_b1_b2-and-YOon_b2_b3) (and (val-on_b1_b2) (val-YOon_b2_b3)))
     (:derived (val-on_b2_b3) (on b2 b3))
    (:action pick-up
        :parameters (?x - block)
        :precondition (and (clear ?x) (ontable ?x) (emptyhand))
        :effect (and (not (ontable ?x)) (not (clear ?x)) (not (emptyhand)) (holding ?x) (when (val-Oon_b1_b2-and-YOon_b2_b3) (Y-Oon_b1_b2-and-YOon_b2_b3)) (when (not (val-Oon_b2_b3)) (not (Y-Oon_b2_b3))) (when (val-Oon_b2_b3) (Y-Oon_b2_b3)) (when (val-Oon_b2_b3) (YOon_b2_b3)) (when (not (val-Oon_b1_b2-and-YOon_b2_b3)) (not (Y-Oon_b1_b2-and-YOon_b2_b3))) (when (not (val-Oon_b2_b3)) (not (YOon_b2_b3))))
    )
     (:action put-down
        :parameters (?x - block)
        :precondition (holding ?x)
        :effect (and (not (holding ?x)) (clear ?x) (emptyhand) (ontable ?x) (when (val-Oon_b1_b2-and-YOon_b2_b3) (Y-Oon_b1_b2-and-YOon_b2_b3)) (when (not (val-Oon_b2_b3)) (not (Y-Oon_b2_b3))) (when (val-Oon_b2_b3) (Y-Oon_b2_b3)) (when (val-Oon_b2_b3) (YOon_b2_b3)) (when (not (val-Oon_b1_b2-and-YOon_b2_b3)) (not (Y-Oon_b1_b2-and-YOon_b2_b3))) (when (not (val-Oon_b2_b3)) (not (YOon_b2_b3))))
    )
     (:action stack
        :parameters (?x - block ?y - block)
        :precondition (and (holding ?x) (clear ?y))
        :effect (and (not (holding ?x)) (not (clear ?y)) (clear ?x) (emptyhand) (on ?x ?y) (when (val-Oon_b1_b2-and-YOon_b2_b3) (Y-Oon_b1_b2-and-YOon_b2_b3)) (when (not (val-Oon_b2_b3)) (not (Y-Oon_b2_b3))) (when (val-Oon_b2_b3) (Y-Oon_b2_b3)) (when (val-Oon_b2_b3) (YOon_b2_b3)) (when (not (val-Oon_b1_b2-and-YOon_b2_b3)) (not (Y-Oon_b1_b2-and-YOon_b2_b3))) (when (not (val-Oon_b2_b3)) (not (YOon_b2_b3))))
    )
     (:action unstack
        :parameters (?x - block ?y - block)
        :precondition (and (on ?x ?y) (clear ?x) (emptyhand))
        :effect (and (holding ?x) (clear ?y) (not (clear ?x)) (not (emptyhand)) (not (on ?x ?y)) (when (val-Oon_b1_b2-and-YOon_b2_b3) (Y-Oon_b1_b2-and-YOon_b2_b3)) (when (not (val-Oon_b2_b3)) (not (Y-Oon_b2_b3))) (when (val-Oon_b2_b3) (Y-Oon_b2_b3)) (when (val-Oon_b2_b3) (YOon_b2_b3)) (when (not (val-Oon_b1_b2-and-YOon_b2_b3)) (not (Y-Oon_b1_b2-and-YOon_b2_b3))) (when (not (val-Oon_b2_b3)) (not (YOon_b2_b3))))
    )
)

new-problem.pddl:

(define (problem bw_10)
    (:domain blocks-domain)
    (:objects b1 - block b2 - block b3 - block)
    (:init (clear b1) (clear b2) (clear b3) (emptyhand) (ontable b1) (ontable b2) (ontable b3))
    (:goal (val-Oon_b1_b2-and-YOon_b2_b3))
)



Note that the new mapping with a smaller problem works well:

plan4past -d domain.pddl -p p2.pddl --goal-inline "O(on_b1_b2)"

where p2.pddl:

(define (problem bw_10)
  (:domain blocks-domain)
  (:objects b1 b2 - block)
  (:init (emptyhand) (ontable b1) (ontable b2) (clear b1) (clear b2))
  (:goal (and (emptyhand)))
)

@marfvr
Copy link
Member Author

marfvr commented Oct 3, 2023

To reproduce the problem in 25bacb0:

this is the domain.pddl file:

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 4 Op-blocks world
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(define (domain blocks-domain)
  (:requirements :disjunctive-preconditions :strips :typing)
  (:types block)
  (:predicates
	       (ontable ?x - block)
	       (on ?x ?y - block)
	       (clear ?x - block)
	       (emptyhand)
	       (holding ?x - block)
	       )

  (:action pick-up
	     :parameters (?x - block)
	     :precondition (and (clear ?x) (ontable ?x) (emptyhand))
	     :effect
	     (and (not (ontable ?x))
		   (not (clear ?x))
		   (not (emptyhand))
		   (holding ?x)))

  (:action put-down
	     :parameters (?x - block)
	     :precondition (holding ?x)
	     :effect
	     (and (not (holding ?x))
		   (clear ?x)
		   (emptyhand)
		   (ontable ?x)))
  (:action stack
	     :parameters (?x ?y - block)
	     :precondition (and (holding ?x) (clear ?y))
	     :effect
	     (and (not (holding ?x))
		   (not (clear ?y))
		   (clear ?x)
		   (emptyhand)
		   (on ?x ?y)))
  (:action unstack
	     :parameters (?x ?y - block)
	     :precondition (and (on ?x ?y) (clear ?x) (emptyhand))
	     :effect
	     (and (holding ?x)
		   (clear ?y)
		   (not (clear ?x))
		   (not (emptyhand))
		   (not (on ?x ?y)))))

This is the problem file:

(define (problem bw_10)
  (:domain blocks-domain)
  (:objects b1 b2 b3 - block)
  (:init (emptyhand) (ontable b1) (ontable b2) (ontable b3) (clear b1) (clear b2) (clear b3))
  (:goal (and (emptyhand)))
)

This is the goal formula:

O(on_b1_b2 & Y(O(on_b2_b3)))

Run:

plan4past -d domain.pddl -p p3.pddl --goal-inline "O(on_b1_b2 & Y(O(on_b2_b3)))"

This produces: new-domain.pddl:

(define (domain blocks-domain)
    (:requirements :conditional-effects :derived-predicates :disjunctive-preconditions :negative-preconditions :strips :typing)
    (:types block)
    (:predicates (Y-quoted_0) (Y-quoted_2) (clear ?x - block)  (emptyhand) (holding ?x - block)  (on ?x - block ?y - block)  (ontable ?x - block)  (quoted_1) (val-quoted_0) (val-quoted_1) (val-quoted_2) (val-quoted_3) (val-quoted_4) (val-quoted_5))
    (:derived (val-quoted_0) (or (val-quoted_3) (Y-quoted_0)))
     (:derived (val-quoted_1) (quoted_1))
     (:derived (val-quoted_2) (or (val-quoted_5) (Y-quoted_2)))
     (:derived (val-quoted_3) (and (val-quoted_4) (val-quoted_1)))
     (:derived (val-quoted_4) (on b1 b2))
     (:derived (val-quoted_5) (on b2 b3))
    (:action pick-up
        :parameters (?x - block)
        :precondition (and (clear ?x) (ontable ?x) (emptyhand))
        :effect (and (not (ontable ?x)) (not (clear ?x)) (not (emptyhand)) (holding ?x) (when (not (val-quoted_2)) (not (Y-quoted_2))) (when (not (val-quoted_0)) (not (Y-quoted_0))) (when (val-quoted_1) (quoted_1)) (when (val-quoted_0) (Y-quoted_0)) (when (val-quoted_2) (Y-quoted_2)) (when (not (val-quoted_1)) (not (quoted_1))))
    )
     (:action put-down
        :parameters (?x - block)
        :precondition (holding ?x)
        :effect (and (not (holding ?x)) (clear ?x) (emptyhand) (ontable ?x) (when (not (val-quoted_2)) (not (Y-quoted_2))) (when (not (val-quoted_0)) (not (Y-quoted_0))) (when (val-quoted_1) (quoted_1)) (when (val-quoted_0) (Y-quoted_0)) (when (val-quoted_2) (Y-quoted_2)) (when (not (val-quoted_1)) (not (quoted_1))))
    )
     (:action stack
        :parameters (?x - block ?y - block)
        :precondition (and (holding ?x) (clear ?y))
        :effect (and (not (holding ?x)) (not (clear ?y)) (clear ?x) (emptyhand) (on ?x ?y) (when (not (val-quoted_2)) (not (Y-quoted_2))) (when (not (val-quoted_0)) (not (Y-quoted_0))) (when (val-quoted_1) (quoted_1)) (when (val-quoted_0) (Y-quoted_0)) (when (val-quoted_2) (Y-quoted_2)) (when (not (val-quoted_1)) (not (quoted_1))))
    )
     (:action unstack
        :parameters (?x - block ?y - block)
        :precondition (and (on ?x ?y) (clear ?x) (emptyhand))
        :effect (and (holding ?x) (clear ?y) (not (clear ?x)) (not (emptyhand)) (not (on ?x ?y)) (when (not (val-quoted_2)) (not (Y-quoted_2))) (when (not (val-quoted_0)) (not (Y-quoted_0))) (when (val-quoted_1) (quoted_1)) (when (val-quoted_0) (Y-quoted_0)) (when (val-quoted_2) (Y-quoted_2)) (when (not (val-quoted_1)) (not (quoted_1))))
    )
)

and problem:

(define (problem bw_10)
    (:domain blocks-domain)
    (:objects b1 - block b2 - block b3 - block)
    (:init (clear b1) (clear b2) (clear b3) (emptyhand) (ontable b1) (ontable b2) (ontable b3))
    (:goal (val-quoted_0))
)

The planner cannot find the plan:

planutils run downward new-domain.pddl new-problem.pddl "--search astar(ff())" 

However, when running it for the old compilation, it works: new-domain.pddl:

(define (domain blocks-domain)
    (:requirements :conditional-effects :derived-predicates :disjunctive-preconditions :negative-preconditions :strips :typing)
    (:types block)
    (:predicates (Y-Oon_b1_b2-and-YOon_b2_b3) (Y-Oon_b2_b3) (YOon_b2_b3) (clear ?x - block)  (emptyhand) (holding ?x - block)  (on ?x - block ?y - block)  (ontable ?x - block)  (val-Oon_b1_b2-and-YOon_b2_b3) (val-Oon_b2_b3) (val-YOon_b2_b3) (val-on_b1_b2) (val-on_b1_b2-and-YOon_b2_b3) (val-on_b2_b3))
    (:derived (val-Oon_b1_b2-and-YOon_b2_b3) (or (val-on_b1_b2-and-YOon_b2_b3) (Y-Oon_b1_b2-and-YOon_b2_b3)))
     (:derived (val-Oon_b2_b3) (or (val-on_b2_b3) (Y-Oon_b2_b3)))
     (:derived (val-YOon_b2_b3) (YOon_b2_b3))
     (:derived (val-on_b1_b2) (on b1 b2))
     (:derived (val-on_b1_b2-and-YOon_b2_b3) (and (val-on_b1_b2) (val-YOon_b2_b3)))
     (:derived (val-on_b2_b3) (on b2 b3))
    (:action pick-up
        :parameters (?x - block)
        :precondition (and (clear ?x) (ontable ?x) (emptyhand))
        :effect (and (not (ontable ?x)) (not (clear ?x)) (not (emptyhand)) (holding ?x) (when (val-Oon_b1_b2-and-YOon_b2_b3) (Y-Oon_b1_b2-and-YOon_b2_b3)) (when (not (val-Oon_b2_b3)) (not (Y-Oon_b2_b3))) (when (val-Oon_b2_b3) (Y-Oon_b2_b3)) (when (val-Oon_b2_b3) (YOon_b2_b3)) (when (not (val-Oon_b1_b2-and-YOon_b2_b3)) (not (Y-Oon_b1_b2-and-YOon_b2_b3))) (when (not (val-Oon_b2_b3)) (not (YOon_b2_b3))))
    )
     (:action put-down
        :parameters (?x - block)
        :precondition (holding ?x)
        :effect (and (not (holding ?x)) (clear ?x) (emptyhand) (ontable ?x) (when (val-Oon_b1_b2-and-YOon_b2_b3) (Y-Oon_b1_b2-and-YOon_b2_b3)) (when (not (val-Oon_b2_b3)) (not (Y-Oon_b2_b3))) (when (val-Oon_b2_b3) (Y-Oon_b2_b3)) (when (val-Oon_b2_b3) (YOon_b2_b3)) (when (not (val-Oon_b1_b2-and-YOon_b2_b3)) (not (Y-Oon_b1_b2-and-YOon_b2_b3))) (when (not (val-Oon_b2_b3)) (not (YOon_b2_b3))))
    )
     (:action stack
        :parameters (?x - block ?y - block)
        :precondition (and (holding ?x) (clear ?y))
        :effect (and (not (holding ?x)) (not (clear ?y)) (clear ?x) (emptyhand) (on ?x ?y) (when (val-Oon_b1_b2-and-YOon_b2_b3) (Y-Oon_b1_b2-and-YOon_b2_b3)) (when (not (val-Oon_b2_b3)) (not (Y-Oon_b2_b3))) (when (val-Oon_b2_b3) (Y-Oon_b2_b3)) (when (val-Oon_b2_b3) (YOon_b2_b3)) (when (not (val-Oon_b1_b2-and-YOon_b2_b3)) (not (Y-Oon_b1_b2-and-YOon_b2_b3))) (when (not (val-Oon_b2_b3)) (not (YOon_b2_b3))))
    )
     (:action unstack
        :parameters (?x - block ?y - block)
        :precondition (and (on ?x ?y) (clear ?x) (emptyhand))
        :effect (and (holding ?x) (clear ?y) (not (clear ?x)) (not (emptyhand)) (not (on ?x ?y)) (when (val-Oon_b1_b2-and-YOon_b2_b3) (Y-Oon_b1_b2-and-YOon_b2_b3)) (when (not (val-Oon_b2_b3)) (not (Y-Oon_b2_b3))) (when (val-Oon_b2_b3) (Y-Oon_b2_b3)) (when (val-Oon_b2_b3) (YOon_b2_b3)) (when (not (val-Oon_b1_b2-and-YOon_b2_b3)) (not (Y-Oon_b1_b2-and-YOon_b2_b3))) (when (not (val-Oon_b2_b3)) (not (YOon_b2_b3))))
    )
)

new-problem.pddl:

(define (problem bw_10)
    (:domain blocks-domain)
    (:objects b1 - block b2 - block b3 - block)
    (:init (clear b1) (clear b2) (clear b3) (emptyhand) (ontable b1) (ontable b2) (ontable b3))
    (:goal (val-Oon_b1_b2-and-YOon_b2_b3))
)

Note that the new mapping with a smaller problem works well:

plan4past -d domain.pddl -p p2.pddl --goal-inline "O(on_b1_b2)"

where p2.pddl:

(define (problem bw_10)
  (:domain blocks-domain)
  (:objects b1 b2 - block)
  (:init (emptyhand) (ontable b1) (ontable b2) (clear b1) (clear b2))
  (:goal (and (emptyhand)))
)

solved offline with @francescofuggitti

Comment on lines 202 to 222
result: Set[When] = set()
for p in predicates:
if p.name.startswith("Y-"):
present_predicate = Predicate(
add_val_prefix(remove_yesterday_prefix(p.name))
)
past_predicate = p
else:
formula = mapping.inverse_mapping[p]
if isinstance(formula, Before):
arg_predicate = mapping.mapping[formula.argument]
present_predicate = Predicate(add_val_prefix(arg_predicate.name))
past_predicate = p
else:
present_predicate = Predicate(add_val_prefix(p.name))
past_predicate = p

positive_when = When(present_predicate, past_predicate)
negative_when = When(Not(present_predicate), Not(past_predicate))
result.update({positive_when, negative_when})
return result
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we cannot just remove the "Y-" prefix since now we have quoted.

However, we still have some predicates as Y-quoted_0, which must be handled with the old approach.

@codecov
Copy link

codecov bot commented Oct 3, 2023

Codecov Report

Merging #265 (6a8aa92) into main (ce48e1e) will decrease coverage by 0.12%.
The diff coverage is 98.00%.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #265      +/-   ##
==========================================
- Coverage   90.95%   90.83%   -0.12%     
==========================================
  Files          22       22              
  Lines         984     1037      +53     
==========================================
+ Hits          895      942      +47     
- Misses         89       95       +6     
Flag Coverage Δ
unittests 90.83% <98.00%> (-0.12%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
plan4past/helpers/utils.py 95.83% <ø> (-4.17%) ⬇️
plan4past/utils/derived_visitor.py 100.00% <100.00%> (ø)
plan4past/utils/predicates_visitor.py 100.00% <100.00%> (ø)
plan4past/utils/val_predicates_visitor.py 100.00% <100.00%> (ø)
plan4past/helpers/compilation_helper.py 90.19% <90.47%> (-0.43%) ⬇️
plan4past/compiler.py 95.50% <90.62%> (-1.24%) ⬇️

Since the mapping from predicate to formula now uses an incremental id with the "quoted_" prefix, the "Y-" prefix to denote yesterday formulas is not needed anymore.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants