/****************************************************************************** * Top contributors (to current version): * Hanna Lachnitt * * This file is part of the cvc5 project. * * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS * in the top-level source directory and their institutional affiliations. * All rights reserved. See the file COPYING in the top-level source * directory for licensing information. * **************************************************************************** * * Enumeration of Alethe proof rules */ #include "cvc5_private.h" #ifndef CVC4__PROOF__ALETHE_PROOF_RULE_H #define CVC4__PROOF__ALETHE_PROOF_RULE_H #include namespace cvc5 { namespace proof { enum class AletheRule : uint32_t { // This enumeration lists all Alethe proof rules. For each rule a list of // steps is given. The last step is the conclusion obtained by applying the // rule in question. There might be zero or more steps occuring before the // conclusion in the proof. A step has the form: // // G > i. F // where G is a context, i is an id and F is a formula. A context may include // substitutions x->y and fixed variables x. For more details see // https://verit.loria.fr/documentation/alethe-spec.pdf // //================================================= Special Rules: Commands // These rules should be printed as commands // // ======== subproof // > i1. F1 // ... // > in. Fn // ... // > j. F // --------------------------------- // > k. (cl (not F1) ... (not Fn) F) // // Each subproof in Alethe begins with an anchor command. The outermost // application of ANCHOR_SUBPROOF will not be printed. ANCHOR_SUBPROOF, // ======== bind // G,y1,...,yn,x1->y1,...,xn->yn > j. (= F1 F2) // ------------------------------------------------------ // G > k. (= (forall (x1 ... xn) F1) (forall (y1 ... yn) F2)) // // where y1,...,yn are not free in (forall (x1,...,xn) F2) ANCHOR_BIND, // ======== input // > i. F ASSUME, //================================================= Rules of the Alethe // calculus // // ======== true // > i. true TRUE, // ======== false // > i. (not true) FALSE, // ======== not_not // > i. (cl (not(not(not F))) F) NOT_NOT, // ======== and_pos // > i. (cl (not(and F1 ... Fn)) Fi) // , with 1 <= i <= n AND_POS, // ======== and_neg // > i. (cl (and F1 ... Fn) (not F1) ... (not Fn)) AND_NEG, // ======== or_pos // > i. (cl (not (or F1 ... Fn)) (not F1) ... (not Fn)) OR_POS, // ======== or_neg // > i. (cl (or F1 ... Fn) (not Fi)) // , with 1 <= i <= n OR_NEG, // ======== xor_pos1 // > i. (cl (not (xor F1 F2)) F1 F2) XOR_POS1, // ======== xor_pos2 // > i. (cl (not (xor F1 F2)) (not F1) (not F2)) XOR_POS2, // ======== xor_neg1 // > i. (cl (xor F1 F2) F1 (not F2)) XOR_NEG1, // ======== xor_neg2 // > i. (cl (xor F1 F2) (not F1) F2) XOR_NEG2, // ======== implies_pos // > i. (cl (not (implies F1 F2)) (not F1) F2) IMPLIES_POS, // ======== implies_neg1 // > i. (cl (implies F1 F2) F1) IMPLIES_NEG1, // ======== implies_neg2 // > i. (cl (implies F1 F2) (not F2)) IMPLIES_NEG2, // ======== equiv_pos1 // > i. (cl (not (= F1 F2)) F1 (not F2)) EQUIV_POS1, // ======== equiv_pos2 // > i. (cl (not (= F1 F2)) (not F1) F2) EQUIV_POS2, // ======== equiv_neg1 // > i. (cl (= F1 F2) (not F1) (not F2)) EQUIV_NEG1, // ======== equiv_neg2 // > i. (cl (= F1 F2) F1 F2) EQUIV_NEG2, // ======== ite_pos1 // > i. (cl (not (ite F1 F2 F3)) F1 F3) ITE_POS1, // ======== ite_pos2 // > i. (cl (not (ite F1 F2 F3)) (not F1) F2) ITE_POS2, // ======== ite_neg1 // > i. (cl (ite F1 F2 F3) F1 (not F3)) ITE_NEG1, // ======== ite_neg2 // > i. (cl (ite F1 F2 F3) (not F1) (not F2)) ITE_NEG2, // ======== eq_reflexive // > i. (= F F) EQ_REFLEXIVE, // ======== eq_transitive // > i. (cl (not (= F1 F2)) ... (not (= F_{n-1} Fn)) (= F1 Fn)) EQ_TRANSITIVE, // ======== eq_congruent // > i. (cl (not (= F1 G1)) ... (not (= Fn Gn)) (= f(F1,...,Fn) // f(G1,...,Gn))) EQ_CONGRUENT, // ======== eq_congruent_pred // > i. (cl (not (= F1 G1)) ... (not (= Fn Gn)) (= P(F1,...,Fn) // P(G1,...,Gn))) EQ_CONGRUENT_PRED, // ======== distinct_elim // If called with one argument: // > i. (= (distinct F) true) // If applied to terms of type Bool more than two terms can never be distinct. // Two cases can be possible: // > i. (= (distinct F G) (not (= F G))) // and // > i. (= (distinct F1 F2 F3 ...) false) // In general: // > i. (= (distinct F1 ... Fn) (AND^n_i=1 (AND^n_j=i+1 (!= Fi Fj)))) DISTINCT_ELIM, // ======== la_rw_eq // > i. (= (= F G) (and (<= F G) (<= G F))) LA_RW_EQ, // Tautology of linear disequalities. // > i. (cl F1 ... Fn) LA_GENERIC, // Tautology of linear integer arithmetic // > i. (cl F1 ... Fn) LIA_GENERIC, // ======== la_disequality // > i. (= (= F G) (not (<= F G)) (not (<= G F))) LA_DISEQUALITY, // ======== la_totality // > i. (or (<= t1 t2) (<= t2 t1)) LA_TOTALITY, // ======== la_tautology // Tautology of linear arithmetic that can be checked without sophisticated // reasoning. LA_TAUTOLOGY, // ======== forall_inst // > i. (or (not (forall (x1 ... xn) P)) P[t1/x1]...[tn/xn]) // args = ((:= x_k1 tk1) ... (:= xkn tkn)) // where k1,...,kn is a permutation of 1,...,n and xi and ki have the same // sort. FORALL_INST, // ======== qnt_join // G > i. (= (Q (x1 ... xn) (Q (xn+1 ... xm) F)) (Q (xk1 ... xko) F)) // where m>n, Q in {forall,exist}, k1...ko is a monotonic map 1,...,m s.t. // xk1,...,xko are pairwise distinct and {x1,...,xm} = {xk1,...,xko}. QNT_JOIN, // ======== qnt_tm_unused // G > i. (= (Q (x1 ... xn) F) (Q (xk1 ... xkm) F)) // where m <= n, Q in {forall,exists}, k1,...,km is monotonic map to 1,...,n // and if x in {xj | j in {1,...,n} and j not in {k1,...,km}} then x is not // free in P QNT_RM_UNUSED, // ======== th_resolution // > i1. (cl F^1_1 ... F^1_k1) // ... // > in. (cl F^n_1 ... F^n_kn) // ... // > i1,...,in. (cl F^r1_s1 ... F^rm_sm) // where (cl F^r1_s1 ... F^rm_sm) are from F^i_j and are the result of a chain // of predicate resolution steps on the clauses i1 to in. This rule is used // when the resolution step is not emitted by the SAT solver. TH_RESOLUTION, // ======== resolution // This rule is equivalent to the th_resolution rule but is emitted by the SAT // solver. RESOLUTION, // ======== refl // G > i. (= F1 F2) REFL, // ======== trans // G > i. (= F1 F2) // ... // G > j. (= F2 F3) // ... // G > k. (= F1 F3) TRANS, // ======== cong // G > i1. (= F1 G1) // ... // G > in. (= Fn Gn) // ... // G > j. (= (f F1 ... Fn) (f G1 ... Gn)) // where f is an n-ary function symbol. CONG, // ======== and // > i. (and F1 ... Fn) // ... // > j. Fi AND, // ======== tautologic_clause // > i. (cl F1 ... Fi ... Fj ... Fn) // ... // > j. true // where Fi != Fj TAUTOLOGIC_CLAUSE, // ======== not_or // > i. (not (or F1 ... Fn)) // ... // > j. (not Fi) NOT_OR, // ======== or // > i. (or F1 ... Fn) // ... // > j. (cl F1 ... Fn) OR, // ======== not_and // > i. (not (and F1 ... Fn)) // ... // > j. (cl (not F1) ... (not Fn)) NOT_AND, // ======== xor1 // > i. (xor F1 F2) // ... // > j. (cl F1 F2) XOR1, // ======== xor2 // > i. (xor F1 F2) // ... // > j. (cl (not F1) (not F2)) XOR2, // ======== not_xor1 // > i. (not (xor F1 F2)) // ... // > j. (cl F1 (not F2)) NOT_XOR1, // ======== not_xor2 // > i. (not (xor F1 F2)) // ... // > j. (cl (not F1) F2) NOT_XOR2, // ======== implies // > i. (=> F1 F2) // ... // > j. (cl (not F1) F2) IMPLIES, // ======== not_implies1 // > i. (not (=> F1 F2)) // ... // > j. (not F2) NOT_IMPLIES1, // ======== not_implies2 // > i. (not (=> F1 F2)) // ... // > j. (not F2) NOT_IMPLIES2, // ======== equiv1 // > i. (= F1 F2) // ... // > j. (cl (not F1) F2) EQUIV1, // ======== equiv2 // > i. (= F1 F2) // ... // > j. (cl F1 (not F2)) EQUIV2, // ======== not_equiv1 // > i. (not (= F1 F2)) // ... // > j. (cl F1 F2) NOT_EQUIV1, // ======== not_equiv2 // > i. (not (= F1 F2)) // ... // > j. (cl (not F1) (not F2)) NOT_EQUIV2, // ======== ite1 // > i. (ite F1 F2 F3) // ... // > j. (cl F1 F3) ITE1, // ======== ite2 // > i. (ite F1 F2 F3) // ... // > j. (cl (not F1) F2) ITE2, // ======== not_ite1 // > i. (not (ite F1 F2 F3)) // ... // > j. (cl F1 (not F3)) NOT_ITE1, // ======== not_ite2 // > i. (not (ite F1 F2 F3)) // ... // > j. (cl (not F1) (not F3)) NOT_ITE2, // ======== ite_intro // > i. (= F (and F F1 ... Fn)) // where F contains the ite operator. Let G1,...,Gn be the terms starting with // ite, i.e. Gi := (ite Fi Hi Hi'), then Fi = (ite Fi (= Gi Hi) (= Gi Hi')) if // Hi is of sort Bool ITE_INTRO, // ======== duplicated_literals // > i. (cl F1 ... Fn) // ... // > j. (cl Fk1 ... Fkm) // where m <= n and k1,...,km is a monotonic map to 1,...,n such that Fk1 ... // Fkm are pairwise distinct and {F1,...,Fn} = {Fk1 ... Fkm} DUPLICATED_LITERALS, // ======== connective_def // G > i. (= (xor F1 F2) (or (and (not F1) F2) (and F1 (not F2)))) // or // G > i. (= (= F1 F2) (and (=> F1 F2) (=> F2 F1))) // or // G > i. (= (ite F1 F2 F3) (and (=> F1 F2) (=> (not F1) (not F3)))) CONNECTIVE_DEF, // ======== Simplify rules // The following rules are simplifying rules introduced as tautologies that can be // verified by a number of simple transformations ITE_SIMPLIFY, EQ_SIMPLIFY, AND_SIMPLIFY, OR_SIMPLIFY, NOT_SIMPLIFY, IMPLIES_SIMPLIFY, EQUIV_SIMPLIFY, BOOL_SIMPLIFY, QUANTIFIER_SIMPLIFY, DIV_SIMPLIFY, PROD_SIMPLIFY, UNARY_MINUS_SIMPLIFY, MINUS_SIMPLIFY, SUM_SIMPLIFY, COMP_SIMPLIFY, NARY_ELIM, QNT_SIMPLIFY, // ======== let // G,x1->F1,...,xn->Fn > j. (= G G') // --------------------------------- // G > k. (= (let (x1 := F1,...,xn := Fn.G) G') LET, // ======== sko_ex // G,x1->(e x1.F),...,xn->(e xn.F) > j. (= F G) // -------------------------------------------- // G > k. (exists (x1 ... xn) (= F G)) SKO_EX, // ======== sko_forall // G,x1->(e x1.(not F)),...,xn->(e xn.(not F)) > j. (= F G) // -------------------------------------------------------- // G > k. (forall (x1 ... xn) (= F G)) SKO_FORALL, // ======== symm // > i. (= F G) // ... // > j. (= G F) SYMM, // ======== not_symm // > i. (not (= F G)) // ... // > j. (not (= G F)) NOT_SYMM, // ======== reorder // > i1. F1 // ... // > j. F2 // where set representation of F1 and F2 are the same and the number of // literals in C2 is the same of that of C1. REORDER, // ======== undefined // Used in case that a step in the proof rule could not be translated. UNDEFINED }; /** * Converts an Alethe proof rule to a string. * * @param id The Alethe proof rule * @return The name of the Alethe proof rule */ const char* aletheRuleToString(AletheRule id); /** * Writes an Alethe proof rule name to a stream. * * @param out The stream to write to * @param id The Alethe proof rule to write to the stream * @return The stream */ std::ostream& operator<<(std::ostream& out, AletheRule id); } // namespace proof } // namespace cvc5 #endif /* CVC4__PROOF__ALETHE_PROOF_RULE_H */