Skip to content

examples: add all_any.pf (list_all / list_any correctness)#788

Merged
jsiek merged 1 commit into
mainfrom
claude/goofy-bhaskara-c25d2b
Jun 2, 2026
Merged

examples: add all_any.pf (list_all / list_any correctness)#788
jsiek merged 1 commit into
mainfrom
claude/goofy-bhaskara-c25d2b

Conversation

@jsiek
Copy link
Copy Markdown
Owner

@jsiek jsiek commented Jun 1, 2026

What

Adds a new introductory-functional-programming worked example to examples/:
the classic higher-order predicates all / any over lists.

Because all and some are reserved keywords in Deduce, the functions are
named list_all and list_any. The file defines both by structural recursion,
includes a handful of assert sanity checks (using an is_even predicate), and
proves three correctness properties:

  1. list_all_appendlist_all distributes over ++ as a conjunction:
    list_all(xs ++ ys, p) = (list_all(xs, p) and list_all(ys, p))
  2. list_any_appendlist_any distributes over ++ as a disjunction:
    list_any(xs ++ ys, p) = (list_any(xs, p) or list_any(ys, p))
  3. list_all_any_de_morgan — the De Morgan duality between them:
    (not list_all(xs, p)) = list_any(xs, fun z { not p(z) })

All proofs go by induction on the list and a switch on p(x). This fills a gap
in the existing examples/ set, which has sum, count, maximum, partition,
take_while, etc., but no Boolean-quantifier example.

Testing

  • python deduce.py examples/all_any.pf → valid
  • make tests-examples → all example files valid under both the
    recursive-descent and LALR parsers.

Notes

While writing this I hit one genuine beginner trap and filed two issues for it:

Claude session

A new introductory-functional-programming worked example defining the
classic `all`/`any` higher-order predicates over lists (named
`list_all`/`list_any` since `all`/`some` are Deduce keywords) and
proving three correctness properties:

  1. list_all_append:       list_all(xs ++ ys, p) = (list_all(xs,p) and list_all(ys,p))
  2. list_any_append:       list_any(xs ++ ys, p) = (list_any(xs,p) or  list_any(ys,p))
  3. list_all_any_de_morgan: (not list_all(xs,p)) = list_any(xs, fun z { not p(z) })

Validates under both the recursive-descent and LALR parsers.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@jsiek jsiek merged commit 75b785b into main Jun 2, 2026
8 checks passed
@jsiek jsiek deleted the claude/goofy-bhaskara-c25d2b branch June 2, 2026 15:02
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.

1 participant