Skip to content

an-integer-abovev and funcallv do not work well together under :gfc #35

@kisp

Description

@kisp

Note: screamer:*strategy* is set to its default value of :gfc here.

The following solution is incorrect:

SCREAMER-USER> (let ((x (an-integer-abovev 1)))
                 (assert! (funcallv #'evenp x))
                 (one-value (solution x (static-ordering #'linear-force))))
1

This returns 1, which is unexpected.

However, using an-integer-betweenv, we get the expected result:

SCREAMER-USER> (let ((x (an-integer-betweenv 1 10)))
                 (assert! (funcallv #'evenp x))
                 (one-value (solution x (static-ordering #'linear-force))))
2

To investigate further, I traced evenp:

SCREAMER-USER> (trace evenp)
(EVENP)
SCREAMER-USER> (let ((x (an-integer-betweenv 1 10)))
                 (assert! (funcallv #'evenp x))
                 (one-value (solution x (static-ordering #'linear-force))))
  0: (EVENP 1)
  0: EVENP returned NIL
  0: (EVENP 2)
  0: EVENP returned T
  0: (EVENP 3)
  0: EVENP returned NIL
  0: (EVENP 4)
  0: EVENP returned T
  0: (EVENP 5)
  0: EVENP returned NIL
  0: (EVENP 6)
  0: EVENP returned T
  0: (EVENP 7)
  0: EVENP returned NIL
  0: (EVENP 8)
  0: EVENP returned T
  0: (EVENP 9)
  0: EVENP returned NIL
  0: (EVENP 10)
  0: EVENP returned T
2

With an-integer-betweenv, evenp is correctly called multiple times.

However, when using an-integer-abovev, evenp is never called:

SCREAMER-USER> (let ((x (an-integer-abovev 1)))
                 (assert! (funcallv #'evenp x))
                 (one-value (solution x (static-ordering #'linear-force))))
1
SCREAMER-USER> 

It seems that funcallv does not properly constrain x when using an-integer-abovev.

The funcallv docstring states:

Additionally, if all but one of V and the argument variables become known, and
the remaining variable has a finite domain, then that domain is further
restricted to be consistent with other arguments.

This explains why, in the case of an-integer-betweenv, the domain is fully pruned by funcallv. Since an-integer-abovev has an infinite domain, this kind of pruning is not possible.

It seems that the funcallv constraint needs to be delayed - but this is not happening.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions