bedrock.prelude.elpi.derive.eq_dec
(*
* Copyright (c) 2023 BedRock Systems, Inc.
* This software is distributed under the terms of the BedRock Open-Source License.
* See the LICENSE-BedRock file in the repository root for details.
*)
Require Import stdpp.decidable.
Require Import elpi.elpi.
Require Export bedrock.prelude.elpi.derive.common.
Require Import bedrock.prelude.elpi.basis.
Elpi Accumulate derive Db bedrock.basis.db.
(***************************************************
EqDecision
***************************************************)
(*For each supported derivation, two predicates:
- myderiv TyGR DerivGR Maps TyGR to its generated derivation
- myderiv-done TyGR We're done deriving myderiv for TyGR.*)
Elpi Db derive.stdpp.eq_dec.db lp:{{
pred eqdec o:gref, o:gref.
pred eqdec-done o:gref.
:name "eqdec-done.typeclass"
eqdec-done GR :-
typeclass "derive.stdpp.eq_dec.db" (before "eqdec-done.typeclass") (eqdec-done GR) {{ @EqDecision lp:{{global GR}} }} Bo_.
}}.
Elpi Accumulate derive Db derive.stdpp.eq_dec.db.
Elpi Typecheck derive.
#[synterp] Elpi Accumulate derive lp:{{
derivation _ _ (derive "eq_dec" (cl\ cl = []) true).
}}.
Elpi Accumulate derive lp:{{
/* [derive.eqdec.main TyGR Prefix Clauses] creates a global instance
* of type [EqDecision lp:{{global TyGR}}].
* It works with any type supported by [solve_decision].
*
* Example of the generated Coq code:
* | (* Inductive C : Set := FOO | BAR | BAZ. *)
* | #[global] Instance C_eq_dec : EqDecision C. Proof. ... Defined.
*/
namespace derive.eqdec {
pred main i:gref, i:string, o:list prop.
main TyGR Prefix Clauses :- std.do! [
InstanceName is Prefix ^ "eq_dec",
derive-original-gref TyGR OrigGR,
TyEqDecision = {{ EqDecision lp:{{global OrigGR}} }},
std.assert-ok! (coq.elaborate-skeleton TyEqDecision _ ETyEqDecision) "[derive.eqdec] [TyEqDecision]",
std.assert-ok! (coq.typecheck {{ lp:BoEqDecision : lp:ETyEqDecision }} _) "typechecking the [EqDecision t] instance failed",
coq.ltac.collect-goals BoEqDecision [SealedGoal] [],
coq.ltac.open (coq.ltac.call "solve_decision" []) SealedGoal [],
coq.env.add-const InstanceName BoEqDecision ETyEqDecision @transparent! C,
@global! => coq.TC.declare-instance (const C) 0,
Clauses = [eqdec-done OrigGR, eqdec OrigGR (const C)],
std.forall Clauses (x\
coq.elpi.accumulate _ "derive.stdpp.eq_dec.db" (clause _ _ x)
),
].
main _ _ _ :- usage.
pred usage.
usage :- coq.error
"Usage: #[only(eq_dec)] derive T where T is an inductive or a definition that unfolds to an inductive. Example #1: Variant T := A | B | C. #[only(eq_dec)] derive T Example #2: #[only(eq_dec)] derive Variant T := A | B | C. Example #3: Variant _T := A | B | C. Definition T := _T. #[only(eq_dec)] derive T.".
}
derivation
(indt T) Prefix ff % inputs
(derive "eq_dec" % name (for dep1)
(derive.eqdec.main (indt T) Prefix) % code to run
(eqdec-done (indt T)) % idempotency test
).
}}.
Elpi Typecheck derive.
* Copyright (c) 2023 BedRock Systems, Inc.
* This software is distributed under the terms of the BedRock Open-Source License.
* See the LICENSE-BedRock file in the repository root for details.
*)
Require Import stdpp.decidable.
Require Import elpi.elpi.
Require Export bedrock.prelude.elpi.derive.common.
Require Import bedrock.prelude.elpi.basis.
Elpi Accumulate derive Db bedrock.basis.db.
(***************************************************
EqDecision
***************************************************)
(*For each supported derivation, two predicates:
- myderiv TyGR DerivGR Maps TyGR to its generated derivation
- myderiv-done TyGR We're done deriving myderiv for TyGR.*)
Elpi Db derive.stdpp.eq_dec.db lp:{{
pred eqdec o:gref, o:gref.
pred eqdec-done o:gref.
:name "eqdec-done.typeclass"
eqdec-done GR :-
typeclass "derive.stdpp.eq_dec.db" (before "eqdec-done.typeclass") (eqdec-done GR) {{ @EqDecision lp:{{global GR}} }} Bo_.
}}.
Elpi Accumulate derive Db derive.stdpp.eq_dec.db.
Elpi Typecheck derive.
#[synterp] Elpi Accumulate derive lp:{{
derivation _ _ (derive "eq_dec" (cl\ cl = []) true).
}}.
Elpi Accumulate derive lp:{{
/* [derive.eqdec.main TyGR Prefix Clauses] creates a global instance
* of type [EqDecision lp:{{global TyGR}}].
* It works with any type supported by [solve_decision].
*
* Example of the generated Coq code:
* | (* Inductive C : Set := FOO | BAR | BAZ. *)
* | #[global] Instance C_eq_dec : EqDecision C. Proof. ... Defined.
*/
namespace derive.eqdec {
pred main i:gref, i:string, o:list prop.
main TyGR Prefix Clauses :- std.do! [
InstanceName is Prefix ^ "eq_dec",
derive-original-gref TyGR OrigGR,
TyEqDecision = {{ EqDecision lp:{{global OrigGR}} }},
std.assert-ok! (coq.elaborate-skeleton TyEqDecision _ ETyEqDecision) "[derive.eqdec] [TyEqDecision]",
std.assert-ok! (coq.typecheck {{ lp:BoEqDecision : lp:ETyEqDecision }} _) "typechecking the [EqDecision t] instance failed",
coq.ltac.collect-goals BoEqDecision [SealedGoal] [],
coq.ltac.open (coq.ltac.call "solve_decision" []) SealedGoal [],
coq.env.add-const InstanceName BoEqDecision ETyEqDecision @transparent! C,
@global! => coq.TC.declare-instance (const C) 0,
Clauses = [eqdec-done OrigGR, eqdec OrigGR (const C)],
std.forall Clauses (x\
coq.elpi.accumulate _ "derive.stdpp.eq_dec.db" (clause _ _ x)
),
].
main _ _ _ :- usage.
pred usage.
usage :- coq.error
"Usage: #[only(eq_dec)] derive T where T is an inductive or a definition that unfolds to an inductive. Example #1: Variant T := A | B | C. #[only(eq_dec)] derive T Example #2: #[only(eq_dec)] derive Variant T := A | B | C. Example #3: Variant _T := A | B | C. Definition T := _T. #[only(eq_dec)] derive T.".
}
derivation
(indt T) Prefix ff % inputs
(derive "eq_dec" % name (for dep1)
(derive.eqdec.main (indt T) Prefix) % code to run
(eqdec-done (indt T)) % idempotency test
).
}}.
Elpi Typecheck derive.