Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Candle: Kernel.compute and record syntax #906

Merged
merged 176 commits into from Aug 25, 2022
Merged

Candle: Kernel.compute and record syntax #906

merged 176 commits into from Aug 25, 2022

Conversation

oskarabrahamsson
Copy link
Contributor

This PR contributes two new features to the Candle theorem prover:

  1. A fast interpreter for terms, called Kernel.compute
  2. Records, implemented as syntactic sugar on top of regular datatypes

Documentation of these features will appear in the Candle repository README once this PR is merged.

myreen and others added 28 commits August 16, 2022 09:37
Record syntax will be implemented as syntactic sugar in the parser.
Declaring a record is done like this:

  type my_rec = Constr of { f1: t1; f2: t2; ...; fN: tN };;

The above declaration is parsed into a datatype declaration and a series
of function declarations for projection, update and construction:

  type my_rec = Constr t1 t2 ... tN
  (* Here, we assume that f1 < f2 < ... < fN; otherwise field names and
     types are sorted and re-ordered *)

  let __f1_record_upd (Constr f1 f2 ... fN) f1 = Constr f1 f2 ... fN;;
  let __f2_record_upd (Constr f1 f2 ... fN) f2 = ...;;
  ...
  let __f1_record_proj (Constr f1 f2 ... fN) = f1;;
  let __f2_record_proj (Constr f1 f2 ... fN) = f2;;
  ...
  let __record_constr_Constr_f1_f2_..._fN =
    fun f1 -> fun f2 -> ... -> fun fN -> Constr f1 f2 ... fN;;

Records with non-distinct field names are rejected. The fields and types
are ordered by the names of the fields. Internally, all records are
regular datatypes. This makes it possible (but unreliable) to pattern
match. For example:

  type myrec = Foo { b: int; a: bool };;

  let foo (Foo a b) = ... (* correct *) ;;
  let foo' (Foo b a) = ... (* incorrect *) ;;

Projection is done with a dot:

  myRecValue . foo (* becomes __foo_record_proj myRecValue *)

'with' updates:

  myRecValue with foo := bar
  (* becomes __foo_record_upd myRecValue bar *)
The previous rule was missing the constructor name, which is needed
to figure out what constructor function to call.
Changed the function that deals with type definitions to also generate a
sequence of projection/update/constructor functions for record type
constructors. The functions are given names that are readable (in case
they pop up in an error message) but impossible to get past the parser.

Some syntactic criteria are checked (e.g., all field names under a
single record constructor must be distinct), but other than that, the
standard semantics is to simply overshadow previous definitions with the
same name.
A FOLDL had snuck in where a FOLDR was needed, meaning that
the record constructor functions were defined with their
arguments appearing backwards.
Without this it isn't possible to detect multi-argument records in
pattern matching, because the parser does not accept multi-argument
constructor patterns/expressions.
@myreen myreen merged commit 1afd9c2 into master Aug 25, 2022
@myreen myreen deleted the candle-features branch August 25, 2022 05:11
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.

None yet

2 participants