Skip to main content
Log in

Adding Decision Procedures to SMT Solvers Using Axioms with Triggers

  • Published:
Journal of Automated Reasoning Aims and scope Submit manuscript

Abstract

Satisfiability modulo theories (SMT) solvers are efficient tools to decide the satisfiability of ground formulas, including a number of built-in theories such as congruence, linear arithmetic, arrays, and bit-vectors. Adding a theory to that list requires delving into the implementation details of a given SMT solver, and is done mainly by the developers of the solver itself. For many useful theories, one can alternatively provide a first-order axiomatization. However, in the presence of quantifiers, SMT solvers are incomplete and exhibit unpredictable behavior. Consequently, this approach can not provide us with a complete and terminating treatment of the theory of interest. In this paper, we propose a framework to solve this problem, based on the notion of instantiation patterns, also known as triggers. Triggers are annotations that suggest instances which are more likely to be useful in proof search. They are implemented in all SMT solvers that handle first-order logic and are included in the SMT-LIB format. In our framework, the user provides a theory axiomatization with triggers, along with a proof of completeness and termination properties of this axiomatization, and obtains a sound, complete, and terminating solver for her theory in return. We describe and prove a corresponding extension of the traditional Abstract DPLL Modulo Theory framework. Implementing this mechanism in a given SMT solver requires a one-time development effort. We have implemented the proposed extension in the Alt-Ergo prover and we discuss some implementation details in the paper. To show that our framework can handle complex theories, we prove completeness and termination of a feature-rich axiomatization of doubly-linked lists. Our tests show that our approach results in a better performance of the solver on goals that stem from the verification of programs manipulating doubly-linked lists and sets.

This is a preview of subscription content, log in via an institution to check access.

Access this article

Price excludes VAT (USA)
Tax calculation will be finalised during checkout.

Instant access to the full article PDF.

Fig. 1
Fig. 2
Fig. 3
Fig. 4
Fig. 5

Similar content being viewed by others

Notes

  1. These three hypothesis are not needed to apply T -Backjump. Still, to implement conflict analysis, we want to make j as small as possible.

  2. http://bware.lri.fr/index.php/BWare_project.

References

  1. Alberti, F., Ghilardi, S., Sharygina, N.: Decision procedures for flat array properties. In: Ábrahám, E., Havelund, K. (eds.) and Algorithms for the Construction and Analysis of Systems. Lecture Notes in Computer Science, vol. 8413, pp. 15–30. Springer, Berlin (2014)

  2. Armando, A., Ranise, S., Rusinowitch, M.: A rewriting approach to satisfiability procedures. Inf. Comput. 183(2), 140–164 (2003). In: 12th International Conference on Rewriting Techniques and Applications (RTA 2001)

  3. Bansal, K., Reynolds, A., King, T., Barrett, C., Wies, T.: Deciding local theory extensions via E-matching. In: Kroening, D., Păsăreanu, C.S. (eds.) Computer Aided Verification, CAV 2015, Lecture Notes in Computer Science. Vol. 9207, pp.87–105 Springer (2015)

  4. Barrett, C., Conway, C.L., Deters, M., Hadarean, L., Jovanović, D., King, T., Reynolds, A., Tinelli, C.: CVC4. In: Gopalakrishnan, G., Qadeer, S. (eds.) Computer Aided Verification. Lecture Notes in Computer Science, vol. 6806, pp. 171–177. Springer, Berlin (2011)

    Chapter  Google Scholar 

  5. Barrett, C., Stump, A., Tinelli, C.: The SMT-LIB standard version 2.0. Technical report, University of Iowa (2010)

  6. Biere, A., Heule, M., van Maaren, H.: Handbook of Satisfiability, vol. 185. IOS Press, Amsterdam (2009)

    MATH  Google Scholar 

  7. Bjørner, N.: Engineering theories with Z3. In: Yang, H. (ed.) Proceedings of the 9th Asian Symposium on Programming Languages and Systems, APLAS 2011, Lecture Notes in Computer Science, vol. 7078, pp. 4–16. Springer, Berlin (2011)

  8. Bobot, F., Conchon, S., Contejean, E., Lescuyer, S.: Implementing polymorphism in SMT solvers. In: SMT’08, ACM ICPS, vol. 367, pp. 1–5. ACM, New York (2008)

  9. Bradley, A.R., Manna, Z., Sipma, H.B.: What’s decidable about arrays? In: Emerson, E.A., Namjoshi, K.S. (eds.) Proceedings of the 7th International Conference on Verification, Model Checking, and Abstract Interpretation (VMCAI 2006). Lecture Notes in Computer Science, vol. 3855, pp. 427–442. Springer, Berlin (2006)

  10. Chatterjee, S., Lahiri, S.K., Qadeer, S., Rakamarić, Z.: A low-level memory model and an accompanying reachability predicate. Int. J. Softw. Tools Technol. Transf. 11(2), 105–116 (2009)

    Article  Google Scholar 

  11. de Moura, L., Bjørner, N.: Efficient E-matching for SMT solvers. In: Pfenning, F. (ed.) CADE-21, LNCS, vol. 4603, pp. 183–198. Springer, Berlin (2007)

  12. de Moura, L., Bjørner, N.: Engineering DPLL(T) \(+\) saturation. In: Armando, A., Baumgartner, P., Dowek, G. (eds.) IJCAR 2008, LNCS, vol. 5195, pp. 475–490. Springer, Berlin (2008)

  13. de Moura, L., Bjørner, N.: Z3: An efficient SMT solver. In: Ramakrishnan, C. R., Rehof, J. (eds.) TACAS 2008, LNCS, vol. 4963, pp. 337–340. Springer (2008)

  14. de Moura, L., Bjørner, N.: Generalized, efficient array decision procedures. In: Biere, A., Pixley, C. (eds.) Formal Methods in Computer-Aided Design, 2009. FMCAD 2009, pp. 45–52. IEEE (2009)

  15. Detlefs, D., Nelson, G., Saxe, J.B.: Simplify: a theorem prover for program checking. J. ACM 52(3), 365–473 (2005)

    Article  MathSciNet  MATH  Google Scholar 

  16. Dross, C., Conchon, S., Kanig, J., Paskevich, A.: Reasoning with triggers. In: 10th International Workshop on Satisfiability Modulo Theories, SMT 2012, pp. 22–31 (2012)

  17. Dross, C., Filliâtre, J.C., Moy, Y.: Correct code containing containers. In: Gogolla, M., Wolff, B. (eds.) Proceedings of the 5th International Conference on Tests and Proofs, TAP’11, Lecture Notes in Computer Science, vol. 6706, pp. 102–118. Springer, Berlin (2011)

  18. Ganzinger, H., Korovin, K.: Theory instantiation. In: Hermann, M., Voronkov, A. (eds.) Logic for Programming, Artificial Intelligence, and Reasoning, LPAR 2006, Lecture Notes in Computer Science, vol. 4246, pp. 497–511. Springer, Berlin (2006)

  19. Ge, Y., Barrett, C., Tinelli, C.: Solving quantified verification conditions using satisfiability modulo theories. In: Pfenning, F. (ed.) CADE-21, LNCS, vol. 4603, pp. 167–182. Springer, Berlin (2007)

  20. Ge, Y., de Moura, L.: Complete instantiation for quantified formulas in satisfiability modulo theories. In: Bouajjani, A., Maler, O. (eds.) Computer Aided Verification, LNCS, vol. 5643, pp. 306–320. Springer (2009)

  21. Goel, A., Krstić, S., Fuchs, A.: Deciding array formulas with frugal axiom instantiation. In: Proceedings of the Joint Workshops of the 6th International Workshop on Satisfiability Modulo Theories and 1st International Workshop on Bit-Precise Reasoning, ACM ICPS, pp. 12–17. ACM, New York (2008)

  22. Jacobs, S., Kuncak, V.: Towards complete reasoning about axiomatic specifications. In: Jhala, R., Schmidt, D. (eds.) Proceedings of VMCAI-12, LNCS, vol. 6538, pp. 278–293. Springer, Berlin (2012)

  23. Knuth, D.E., Bendix, P.B.: Simple word problems in universal algebras. In: Automation of Reasoning, Symbolic Computation, pp. 342–376. Springer, Berlin (1983)

  24. Korovin, K.: iProver—an instantiation-based theorem prover for first-order logic (system description). In: Armando, A., Baumgartner, P., Dowek, G. (eds.) Proceedings of the 4th International Joint Conference on Automated Reasoning, (IJCAR 2008), Lecture Notes in Computer Science, vol. 5195, pp. 292–298. Springer, Berlin (2008)

  25. Korovin, K.: Instantiation-based reasoning: from theory to practice. In: Schmidt, R.A. (ed.) 22nd International Conference on Automated Deduction, CADE’22, Lecture Notes in Computer Science, vol. 5663, pp. 163–166. Springer, Berlin (2009)

  26. Lynch, C., Morawska, B.: Automatic decidability. In: Proceedings of the 17th Annual IEEE Symposium on Logic in Computer Science, pp. 7–16. IEEE (2002)

  27. Lynch, C., Ranise, S., Ringeissen, C., Tran, D.K.: Automatic decidability and combinability. Inf. Comput. 209(7), 1026–1047 (2011)

    Article  MathSciNet  MATH  Google Scholar 

  28. McPeak, S., Necula, G.C.: Data structure specifications via local equality axioms. In: Etessami, K., Rajamani,S.K. (eds.) Computer Aided Verification, CAV 2005, Lecture Notes in Computer Science, vol. 3576, pp. 476–490. Springer, Berlin (2005)

  29. Moskal, M.: Programming with triggers. In: Proceedings of the 7th International Workshop on Satisfiability Modulo Theories, ACM ICPS, pp. 20–29. ACM, New York (2009)

  30. Nelson, G.: Techniques for program verification. Technical Report CSL81-10, Xerox Palo Alto Research Center (1981)

  31. Nieuwenhuis, R., Oliveras, A., Tinelli, C.: Solving SAT and SAT modulo theories: from an abstract Davis–Putnam–Logemann–Loveland procedure to DPLL(T). J. ACM 53(6), 937–977 (2006)

    Article  MathSciNet  MATH  Google Scholar 

  32. Piskac, R., Wies, T., Zufferey, D.: Automating separation logic using SMT. In: Sharygina, N., Veith, H. (eds.) Computer Aided Verification, CAV 2013, Lecture Notes in Computer Science, Vol. 8044, pp. 773–789. Springer, Berlin (2013)

  33. Rümmer, P.: E-matching with free variables. In: Voronkov, A., Bjørner, N. (eds.) Logic for Programming, Artificial Intelligence, and Reasoning: 18th International Conference, LPAR-18, LNCS, vol. 7180, pp. 359–374. Springer, Berlin (2012)

  34. Suter, P., Steiger, R., Kuncak, V.: Sets with cardinality constraints in satisfiability modulo theories. In: Jhala, R., Schmidt, D. (eds.) Verification, Model Checking, and Abstract Interpretation. Lecture Notes in Computer Science, vol. 6538, pp. 403–418. Springer, Berlin (2011)

    Chapter  Google Scholar 

Download references

Acknowledgments

We would like to thank the anonymous reviewers for their careful reading of our article, as well as their helpful comments which greatly contributed to the quality of this paper. This work is partially supported by the BWare Project (ANR-12-INSE-0010, http://bware.lri.fr/) and the Joint Laboratory ProofInUse (ANR-13-LAB3-0007, http://www.spark-2014.org/proofinuse) of the French national research organization.

Author information

Authors and Affiliations

Authors

Corresponding author

Correspondence to Claire Dross.

Appendix: Axiomatization of Imperative Doubly-Linked Lists

Appendix: Axiomatization of Imperative Doubly-Linked Lists

  • length_gte_zero:

    $$\begin{aligned} \begin{array}{l}\forall l{:}\,list. [length(l)] length(l)\ge 0\end{array} \end{aligned}$$
  • is_empty:

    $$\begin{aligned} \begin{array}{l}\forall l{:}\,list. [is\_empty(l)] is\_empty(l)\approx {\mathtt {t}}\leftrightarrow length(l)\approx 0\end{array} \end{aligned}$$
  • empty_is_empty:

    $$\begin{aligned} \begin{array}{l} is\_empty(empty)\end{array} \end{aligned}$$
  • equal_elements_refl:

    $$\begin{aligned} \forall e{:}\,element\_type. [equal\_elements(e,e)]equal\_elements(e,e)\approx {\mathtt {t}} \end{aligned}$$
  • equal_elements_sym:

    $$\begin{aligned} \begin{array}{l}\forall e_1 e_2{:}\,element\_type. [equal\_elements(e_1,e_2)]\\ equal\_elements(e_1,e_2)\approx equal\_elements(e_2,e_1)\end{array} \end{aligned}$$
  • equal_elements_trans:

    $$\begin{aligned} \begin{array}{l}\forall e_1 e_2 e_3{:}\,element\_type. [equal\_elements(e_1,e_2), equal\_elements(e_2,e_3)]\\ equal\_elements(e_1,e_2)\approx {\mathtt {t}}\rightarrow equal\_elements(e_2, e_3)\approx {\mathtt {t}}\rightarrow {}\\ equal\_elements(e_1,e_3)\approx {\mathtt {t}}\\ \forall e_1 e_2 e_3{:}\,element\_type. [equal\_elements(e_1,e_2), equal\_elements(e_1,e_3)]\\ equal\_elements(e_1,e_2)\approx {\mathtt {t}}\rightarrow equal\_elements(e_2, e_3)\approx {\mathtt {t}}\rightarrow {}\\ equal\_elements(e_1,e_3)\approx {\mathtt {t}}\end{array} \end{aligned}$$
  • position_gte_zero:

    $$\begin{aligned} \begin{array}{l} \forall l{:}\,list, c{:}\,cursor. [position(l, c)]\\ length(l)\ge position(l,c)\wedge position(l,c)\ge 0\end{array} \end{aligned}$$
  • positionno_element:

    $$\begin{aligned} \begin{array}{l} \forall l{:}\,list. [position(l,no\_element)]position(l,no\_element)\approx 0\end{array} \end{aligned}$$
  • position_eq:

    $$\begin{aligned} \begin{array}{l} \forall l{:}\,list, c_1 c_2{:}\,cursor. [position(l,c_1),position(l,c_2)]\\ position(l,c_1)> 0\rightarrow position(l,c_1)\approx position(l,c_2)\rightarrow c_1\approx c_2\end{array} \end{aligned}$$
  • previous_in:

    $$\begin{aligned} \begin{array}{l} \forall l{:}\,list, c{:}\,cursor. [previous(l,c)]\\ (position(l,c)> 1\vee position(l,previous(l,c))> 0)\rightarrow {}\\ position(l,previous(l,c))\approx position(l,c)-1 \end{array} \end{aligned}$$
  • previous_ext:

    $$\begin{aligned} \begin{array}{l} \forall l{:}\,list, c{:}\,cursor. [previous(l,c)]\\ (position(l,c)\approx 1\vee c\approx no\_element)\rightarrow previous(l,c)\approx no\_element \end{array} \end{aligned}$$
  • next_in:

    $$\begin{aligned} \begin{array}{l} \forall l{:}\,list, c{:}\,cursor. [next(l,c)]\\ (length(l)>position(l,c)>0\vee position(l,next(l,c))> 0)\rightarrow {}\\ position(l,next(l,c))\approx position(l,c)+1 \end{array} \end{aligned}$$
  • next_ext:

    $$\begin{aligned} \begin{array}{l} \forall l{:}\,list, c{:}\,cursor. [next(l,c)]\\ (position(l,c)\approx length(l)\vee c\approx no\_element)\rightarrow next(l,c)\approx no\_element \end{array} \end{aligned}$$
  • last_empty:

    $$\begin{aligned} \begin{array}{l} \forall l{:}\,list. [last(l)]length(l)\approx 0\leftrightarrow last(l)\approx no\_element \end{array} \end{aligned}$$
  • last_gen:

    $$\begin{aligned} \begin{array}{l} \forall l{:}\,list. [last(l)]length(l)\approx position(l,last(l)) \end{array} \end{aligned}$$
  • first_empty:

    $$\begin{aligned} \begin{array}{l} \forall l{:}\,list. [first(l)]length(l)\approx 0\leftrightarrow first(l)\approx no\_element \end{array} \end{aligned}$$
  • first_gen:

    $$\begin{aligned} \begin{array}{l} \forall l{:}\,list. [first(l)]length(l)>0\rightarrow position(l,first(l))\approx 1 \end{array} \end{aligned}$$
  • has_element_def:

    $$\begin{aligned} \begin{array}{l} \forall l{:}\,list, c{:}\,cursor. [has\_element(l,c)]position(l,c)>0\leftrightarrow has\_element(l,c)\approx {\mathtt {t}} \end{array} \end{aligned}$$
  • left_no_element:

    $$\begin{aligned} \begin{array}{l}\forall l{:}\,list. [left(l,no\_element)]left(l,no\_element)\approx l \end{array} \end{aligned}$$
  • left_length:

    $$\begin{aligned} \begin{array}{l}\forall l{:}\,list, c{:}\,cursor. [left(l,c)]\\ position(l,c)>0\rightarrow length(left(l,c))\approx position(l,c) - 1\end{array} \end{aligned}$$
  • left_position_in:

    $$\begin{aligned} \begin{array}{l}\forall l{:}\,list, c_1 c_2{:}\,cursor.[position(left(l,c_1),c_2)]\\ (position(left(l,c_1),c_2)>0\vee position(l,c_2)<position(l,c_1))\rightarrow {}\\ position(left(l,c_1),c_2)\approx position(l,c_2)\\ \forall l{:}\,list, c_1 c_2{:}\,cursor.[left(l,c_1),position(l,c_2)]\\ (position(left(l,c_1),c_2)>0\vee position(l,c_2)<position(l,c_1))\rightarrow {}\\ position(left(l,c_1),c_2)\approx position(l,c_2)\end{array} \end{aligned}$$
  • left_position_ext:

    $$\begin{aligned} \begin{array}{l}\forall l{:}\,list, c_1 c_2{:}\,cursor.[position(left(l,c_1),c_2)]\\ position(l,c_2)\ge position(l,c_1))>0\rightarrow {}\\ position(left(l,c_1),c_2)\approx 0\end{array} \end{aligned}$$
  • left_element:

    $$\begin{aligned} \begin{array}{l}\forall l{:}\,list, c_1 c_2{:}\,cursor.[element(left(l,c_1),c_2)]\\ (position(left(l,c_1),c_2)>0\vee 0<position(l,c_2)<position(l,c_1))\rightarrow {}\\ element(left(l,c_1),c_2)\approx element(l,c_2)\\ \forall l{:}\,list, c_1 c_2{:}\,cursor.[left(l,c_1),element(l,c_2)]\\ (position(left(l,c_1),c_2)>0\vee 0<position(l,c_2)<position(l,c_1))\rightarrow {}\\ element(left(l,c_1),c_2)\approx element(l,c_2)\end{array} \end{aligned}$$
  • right_no_element:

    $$\begin{aligned} \begin{array}{l}\forall l{:}\,list. [right(l,no\_element)]right(l,no\_element)\approx empty\end{array} \end{aligned}$$
  • right_length:

    $$\begin{aligned} \begin{array}{l}\forall l{:}\,list, c{:}\,cursor. [right(l,c)]\\ position(l,c)>0\rightarrow length(right(l,c))\approx length(l) - position(l,c) + 1\end{array} \end{aligned}$$
  • right_position_in:

    $$\begin{aligned} \begin{array}{l}\forall l{:}\,list, c_1 c_2{:}\,cursor.[position(right(l,c_1),c_2)]\\ (position(right(l,c_1),c_2)>0\vee 0<position(l,c_1)\le position(l,c_2))\rightarrow {}\\ position(right(l,c_1),c_2)\approx position(l,c_2) - position(l,c_1) + 1\\ \forall l{:}\,list, c_1 c_2{:}\,cursor.[right(l,c_1),position(l,c_2)]\\ (position(right(l,c_1),c_2)>0\vee 0<position(l,c_1)\le position(l,c_2))\rightarrow {}\\ position(right(l,c_1),c_2)\approx position(l,c_2) - position(l,c_1) + 1\end{array} \end{aligned}$$
  • right_position_ext:

    $$\begin{aligned} \begin{array}{l}\forall l{:}\,list, c_1 c_2{:}\,cursor.[position(right(l,c_1),c_2)]\\ position(l,c_2)< position(l,c_1))\rightarrow {}\\ position(right(l,c_1),c_2)\approx 0\end{array} \end{aligned}$$
  • right_element:

    $$\begin{aligned} \begin{array}{l}\forall l{:}\,list, c_1 c_2{:}\,cursor.[element(right(l,c_1),c_2)]\\ (position(right(l,c_1),c_2)>0\vee 0<position(l,c_1)\le position(l,c_2))\rightarrow {}\\ element(right(l,c_1),c_2)\approx element(l,c_2)\\ \forall l{:}\,list, c_1 c_2{:}\,cursor.[right(l,c_1),element(l,c_2)]\\ (position(right(l,c_1),c_2)>0\vee 0<position(l,c_1)\le position(l,c_2))\rightarrow {}\\ element(right(l,c_1),c_2)\approx element(l,c_2)\end{array} \end{aligned}$$
  • find_first_range:

    $$\begin{aligned} \begin{array}{l}\forall l{:}\,list, e{:}\,element\_type. [find\_first(l,e)]\\ find\_first(l,e)\approx no\_element\vee position(l,find\_first(l,e))>0\end{array} \end{aligned}$$
  • find_first_not:

    $$\begin{aligned} \begin{array}{l}\forall l{:}\,list, e{:}\,element\_type, c : cursor.[find\_first(l,e),element(l,c)]\\ find\_first(l,e)\approx no\_element\rightarrow position(l,c)>0\rightarrow {}\\ equal\_elements(element(l,c),e)\not \approx {\mathtt {t}}\end{array} \end{aligned}$$
  • find_first_first:

    $$\begin{aligned} \begin{array}{l}\forall l{:}\,list, e{:}\,element\_type, c : cursor.[find\_first(l,e),element(l,c)]\\ 0<position(l,c)<position(l,find\_first(l,e))\rightarrow {}\\ equal\_elements(element(l,c),e)\not \approx {\mathtt {t}}\end{array} \end{aligned}$$
  • find_first_element:

    $$\begin{aligned} \begin{array}{l}\forall l{:}\,list, e{:}\,element\_type.[find\_first(l,e)]0<position(l,find\_first(l,e))\rightarrow {}\\ equal\_elements(element(l,find\_first(l,e)),e)\approx {\mathtt {t}}\end{array} \end{aligned}$$
  • contains_def:

    $$\begin{aligned} \begin{array}{l}\forall l{:}\,list, e{:}\,element\_type.[contains(l,e)]\\ contains(l,e)\leftrightarrow 0<position(l,find\_first(l,e))\end{array} \end{aligned}$$
  • find_first:

    $$\begin{aligned} \begin{array}{l}\forall l{:}\,list, e{:}\,element\_type.[find(l,e,no\_element)]\\ find(l,e,no\_element)\approx find\_first(l,e)\end{array} \end{aligned}$$
  • find_others:

    $$\begin{aligned} \begin{array}{l}\forall l{:}\,list, e{:}\,element\_type, c{:}\,cursor.[find(l,e,c)]\\ position(l,c)>0\rightarrow find(l,e,c)\approx find\_first(right(l,c),e)\end{array} \end{aligned}$$
  • replace_element_range:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list, c{:}\,cursor, e{:}\,element\_type .[replace\_element(l_1,c,e,l_2)]\\ replace\_element(l_1,c,e,l_2)\approx {\mathtt {t}}\rightarrow position(l_1,c)>0\end{array} \end{aligned}$$
  • replace_element_length:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list, c{:}\,cursor, e{:}\,element\_type .[replace\_element(l_1,c,e,l_2)]\\ replace\_element(l_1,c,e,l_2)\approx {\mathtt {t}}\rightarrow length(l_1)\approx length(l_2)\end{array} \end{aligned}$$
  • replace_element_position:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list, c_1 c_2{:}\,cursor, e{:}\,element\_type .[replace\_element(l_1,c_1,e,l_2),\\ position(l_1,c_2]\\ replace\_element(l_1,c_1,e,l_2)\approx {\mathtt {t}}\rightarrow position(l_1,c_2)\approx position(l_2,c_2)\\ \forall l_1 l_2{:}\,list, c_1 c_2{:}\,cursor, e{:}\,element\_type .[replace\_element(l_1,c_1,e,l_2),\\ position(l_2,c_2]\\ replace\_element(l_1,c_1,e,l_2)\approx {\mathtt {t}}\rightarrow position(l_1,c_2)\approx position(l_2,c_2)\end{array} \end{aligned}$$
  • replace_element_element_in:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list, c{:}\,cursor, e{:}\,element\_type .[replace\_element(l_1,c,e,l_2)]\\ replace\_element(l_1,c,e,l_2)\approx {\mathtt {t}}\rightarrow element(l_2,c)\approx e\end{array} \end{aligned}$$
  • replace_element_element_ext:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list, c_1 c_2{:}\,cursor, e{:}\,element\_type .[replace\_element(l_1,c_1,e,l_2),\\ element(l_1,c_2)]\\ (replace\_element(l_1,c_1,e,l_2)\approx {\mathtt {t}}\wedge position(l_1,c_2)>0\wedge c_1\not \approx c_2)\rightarrow {}\\ element(l_1,c_2)\approx element(l_2,c_2)\\ \forall l_1 l_2{:}\,list, c_1 c_2{:}\,cursor, e{:}\,element\_type .[replace\_element(l_1,c_1,e,l_2),\\ element(l_2,c_2)]\\ (replace\_element(l_1,c_1,e,l_2)\approx {\mathtt {t}}\wedge position(l_1,c_2)>0\wedge c_1\not \approx c_2)\rightarrow {}\\ element(l_1,c_2)\approx element(l_2,c_2)\end{array} \end{aligned}$$
  • insert_range:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list, c{:}\,cursor, e{:}\,element\_type .[insert(l_1,c,e,l_2)]\\ insert(l_1,c,e,l_2)\approx {\mathtt {t}}\rightarrow c\approx no\_element\vee position(l_1,c)>0\end{array} \end{aligned}$$
  • insert_length:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list, c{:}\,cursor, e{:}\,element\_type .[insert(l_1,c,e,l_2)]\\ insert(l_1,c,e,l_2)\approx {\mathtt {t}}\rightarrow length(l_2)\approx length(l_1)+1\end{array} \end{aligned}$$
  • insert_new:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list, c{:}\,cursor, e{:}\,element\_type .[insert(l_1,c,e,l_2)]\\ (insert(l_1,c,e,l_2)\approx {\mathtt {t}}\wedge position(l_1,c)>0)\rightarrow {}\\ position(l_1,previous(l_2,c))\approx 0\wedge element(l_2,previous(l_2,c))\approx e\end{array} \end{aligned}$$
  • insert_new_no_element:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list, c{:}\,cursor, e{:}\,element\_type .[insert(l_1,no\_element,e,l_2)]\\ insert(l_1,no\_element,e,l_2)\approx {\mathtt {t}}\rightarrow {}\\ position(l_1,last(l_2))\approx 0\wedge element(l_2,last(l_2))\approx e\end{array} \end{aligned}$$
  • insert_position_before:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list, c_1 c_2{:}\,cursor, e{:}\,element\_type .[insert(l_1,c_1,e,l_2),position(l_1,c_2)]\\ (insert(l_1,c_1,e,l_2)\approx {\mathtt {t}}\wedge 0<position(l_1,c_2)<position(l_1,c_1))\rightarrow {}\\ position(l_1,c_2)\approx position(l_2,c_2)\\ \forall l_1 l_2{:}\,list, c_1 c_2{:}\,cursor, e{:}\,element\_type .[insert(l_1,c_1,e,l_2),position(l_2,c_2)]\\ (insert(l_1,c_1,e,l_2)\approx {\mathtt {t}}\wedge position(l_2,c_2)<position(l_1,c_1))\rightarrow {}\\ position(l_1,c_2)\approx position(l_2,c_2)\end{array} \end{aligned}$$
  • insert_position_after:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list, c_1 c_2{:}\,cursor, e{:}\,element\_type .[insert(l_1,c_1,e,l_2),position(l_1,c_2)]\\ (insert(l_1,c_1,e,l_2)\approx {\mathtt {t}}\wedge position(l_1,c_2)\ge position(l_1,c_1)>0)\rightarrow {}\\ position(l_1,c_2)+1\approx position(l_2,c_2)\\ \forall l_1 l_2{:}\,list, c_1 c_2{:}\,cursor, e{:}\,element\_type .[insert(l_1,c_1,e,l_2),position(l_2,c_2)]\\ (insert(l_1,c_1,e,l_2)\approx {\mathtt {t}}\wedge position(l_2,c_2)>position(l_1,c_1)>0)\rightarrow {}\\ position(l_1,c_2)+1\approx position(l_2,c_2)\end{array} \end{aligned}$$
  • insert_position_no_element:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list, c{:}\,cursor, e{:}\,element\_type .[insert(l_1,no\_element,e,l_2),position(l_1,c)]\\ (insert(l_1,no\_element,e,l_2)\approx {\mathtt {t}}\wedge position(l_1,c)>0)\rightarrow {}\\ position(l_1,c)\approx position(l_2,c)\\ \forall l_1 l_2{:}\,list, c{:}\,cursor, e{:}\,element\_type .[insert(l_1,no\_element,e,l_2),position(l_2,c)]\\ (insert(l_1,no\_element,e,l_2)\approx {\mathtt {t}}\wedge position(l_2,c_2)<length(l_2))\rightarrow {}\\ position(l_1,c)\approx position(l_2,c)\end{array} \end{aligned}$$
  • insert_element:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list, c_1 c_2{:}\,cursor, e{:}\,element\_type .[insert(l_1,c_1,e,l_2),element(l_1,c_2)]\\ (insert(l_1,c_1,e,l_2)\approx {\mathtt {t}}\wedge position(l_1,c_2)>0)\rightarrow {}\\ element(l_1,c_2)\approx element(l_2,c_2)\\ \forall l_1 l_2{:}\,list, c_1 c_2{:}\,cursor, e{:}\,element\_type .[insert(l_1,c_1,e,l_2),element(l_2,c_2)]\\ (insert(l_1,c_1,e,l_2)\approx {\mathtt {t}}\wedge position(l_1,c_2)>0)\rightarrow {}\\ element(l_1,c_2)\approx element(l_2,c_2)\end{array} \end{aligned}$$
  • delete_range:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list, c{:}\,cursor .[delete(l_1,c,l_2)]\\ delete(l_1,c,l_2)\approx {\mathtt {t}}\rightarrow position(l_1,c)>0\end{array} \end{aligned}$$
  • delete_length:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list, c{:}\,cursor .[delete(l_1,c,l_2)]\\ delete(l_1,c,l_2)\approx {\mathtt {t}}\rightarrow length(l_2)+1\approx length(l_1)\end{array} \end{aligned}$$
  • delete_position_before:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list, c_1 c_2{:}\,cursor .[delete(l_1,c_1,l_2),position(l_1,c_2)]\\ (delete(l_1,c_1,l_2)\approx {\mathtt {t}}\wedge position(l_1,c_2)<position(l_1,c_1))\rightarrow {}\\ position(l_1,c_2)\approx position(l_2,c_2)\\ \forall l_1 l_2{:}\,list, c_1 c_2{:}\,cursor .[delete(l_1,c_1,l_2),position(l_2,c_2)]\\ (delete(l_1,c_1,l_2)\approx {\mathtt {t}}\wedge 0<position(l_2,c_2)<position(l_1,c_1))\rightarrow {}\\ position(l_1,c_2)\approx position(l_2,c_2)\end{array} \end{aligned}$$
  • delete_position_after:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list, c_1 c_2{:}\,cursor .[delete(l_1,c_1,l_2),position(l_1,c_2)]\\ (delete(l_1,c_1,l_2)\approx {\mathtt {t}}\wedge position(l_1,c_2)>position(l_1,c_1))\rightarrow {}\\ position(l_1,c_2)\approx position(l_2,c_2)+1\\ \forall l_1 l_2{:}\,list, c_1 c_2{:}\,cursor .[delete(l_1,c_1,l_2),position(l_2,c_2)]\\ (delete(l_1,c_1,l_2)\approx {\mathtt {t}}\wedge position(l_2,c_2)\ge position(l_1,c_1))\rightarrow {}\\ position(l_1,c_2)\approx position(l_2,c_2)+1\end{array} \end{aligned}$$
  • delete_position_next:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list, c{:}\,cursor .[delete(l_1,c,l_2)]delete(l_1,c,l_2)\approx {\mathtt {t}}\rightarrow \langle next(l_1, c)\rangle {\mathtt {t}}\end{array} \end{aligned}$$
  • delete_element:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list, c_1 c_2{:}\,cursor .[delete(l_1,c_1,l_2),element(l_1,c_2)]\\ (delete(l_1,c,l_2)\approx {\mathtt {t}}\wedge position(l_2,c_2)>0)\rightarrow {}\\ element(l_1,c_2)=element(l_2,c_2)\end{array} \end{aligned}$$
  • equal_lists_position:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list .[equal\_lists(l_1,l_2)]equal\_lists(l_1,l_2)\approx {\mathtt {t}}\rightarrow {}\\ (\forall c{:}\,cursor. [position(l_1, c)] position(l_1, c)\approx position(l_2, c))\wedge {}\\ (\forall c{:}\,cursor. [position(l_2, c)] position(l_1, c)\approx position(l_2, c))\end{array} \end{aligned}$$
  • equal_lists_element:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list .[equal\_lists(l_1,l_2)]equal\_lists(l_1,l_2)\approx {\mathtt {t}}\rightarrow {}\\ (\forall c{:}\,cursor. [element(l_1, c)] position(l_1, c)>0\rightarrow \\ element(l_1,c)\approx element(l_2, c))\wedge {}\\ (\forall c{:}\,cursor. [element(l_2, c)] position(l_1, c)>0\rightarrow \\ element(l_1,c)\approx element(l_2, c))\end{array} \end{aligned}$$
  • equal_lists_inv:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list .[equal\_lists(l_1,l_2)]equal\_lists(l_1,l_2)\not \approx {\mathtt {t}}\rightarrow {}\\ (\exists c{:}\,cursor. position(l_1,c)>0\wedge {}\\ (position(l_1,c)\approx position (l_2,c)\rightarrow element(l_1,c)\not \approx element(l_2, c)))\end{array} \end{aligned}$$
  • equal_lists_length:

    $$\begin{aligned} \begin{array}{l}\forall l_1 l_2{:}\,list .[equal\_lists(l_1,l_2)]equal\_lists(l_1,l_2)\approx {\mathtt {t}}\rightarrow length(l_1)\approx length(l_2)\end{array} \end{aligned}$$

Rights and permissions

Reprints and permissions

About this article

Check for updates. Verify currency and authenticity via CrossMark

Cite this article

Dross, C., Conchon, S., Kanig, J. et al. Adding Decision Procedures to SMT Solvers Using Axioms with Triggers. J Autom Reasoning 56, 387–457 (2016). https://doi.org/10.1007/s10817-015-9352-2

Download citation

  • Received:

  • Accepted:

  • Published:

  • Issue Date:

  • DOI: https://doi.org/10.1007/s10817-015-9352-2

Keywords

Mathematics Subject Classification

Navigation