Skip to main content
Log in

Speed Up the Conception of Logical Systems with Test-Driven Development

  • Published:
Journal of Logic, Language and Information Aims and scope Submit manuscript

Abstract

In this paper, I stress the utility of employing test-driven development (TDD) for conceiving logical systems. TDD, originally invented in the context of Extreme Programming, is a methodology widely used by software engineers to conceive and develop programs. Its main principle is to design the tests of the expected properties of the system before the development phase. I argue that this methodology is especially convenient in conceiving applied logics. Indeed, this technique is efficient with most decidable logics having a software implementation. Having a clear list of the desired inferences right from the beginning makes it possible to refine the properties of the system step by step until its completion. I distinguish and detail seven advantages of the usage of TDD for the conception of a logical theory. Most importantly, this methodology increases the predictability of the inferential power of the theory. A second important benefit is that the time required for the conception of the logic goes down dramatically. This methodology will change both ideas and practices. Logic is no longer considered to be a formal science, but rather to be an empirical one. Research in the field is geared toward specific and concrete goals. Programs are considered tools used to verify the conformity of formal theories. To sum up, I defend the view that, in some situations, this way of designing a formal system brings significant benefits, and that the construction of new logics can be conducted similarly to the development of open source software.

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

Similar content being viewed by others

Notes

  1. These three parts are now completely standard, as stated by the very first sentence of Shapiro (2009): “Typically, a logic consists of a formal or informal language together with a deductive system and/or a model-theoretic semantic”.

  2. The Apache Ant project. http://ant.apache.org/.

  3. The Apache Maven project. http://maven.apache.org/.

  4. Depending on your taste, you could also construct the deductive system before the semantics.

  5. For an examination of the different significations of formal logic, see Béziau (1998).

  6. See Boole (2010), Section 4, Chapter I.

  7. They belong to a third realm, different from the realm of the things of the outer world and from the realm of our psychological ideas. See Frege (1956).

  8. I assume the simplest case where a deduction has only one consequence but the idea can be easily expanded to cover more complex consequence relations.

References

  • Adams, E. W. (1975). The logic of conditionals. Dordrecht: Reidel.

    Book  Google Scholar 

  • Areces, C. (2000). Logic engineering. The case of description and hybrid logics. Ph.D. thesis, ILLC, University of Amsterdam.

  • Austin, J. L. (1961). Ifs and cans. In J. O. Urmson & G. J. Warnock (Eds.), Philosophical papers (pp. 153–180). Oxford: Oxford University Press.

  • Beck, K. (1999). Extreme programming explained: Embracing change. Reading, MA: Addison-Wesley.

    Google Scholar 

  • Beck, K., Gamma, E. (2002). The junit cookbook. http://junit.sourceforge.net/doc/cookbook/cookbook.htm.

  • Béziau, J. Y. (1998). What is formal logic? http://www.jyb-logic.org/jyb-form-final-sp.pdf.

  • Blackburn, P., de Rijke, M., & Venema, Y. (2002). Modal logic. Cambridge tracts in theoretical computer science. Cambridge: Cambridge University Press.

    Google Scholar 

  • Boole, G. (2010). An investigation of the laws of thought: On which are founded the mathematical theories of logic and probabilities. Rough draft printing. First published: 1854.

  • Cortex, I. (2003). Statistics over IT projects failure rate. http://www.it-cortex.com/Stat_Failure_Rate.htm.

  • Davies, E. (1979). Some restrictions on conditional imperatives. Linguistics, 17, 1039–1054.

    Article  Google Scholar 

  • Fox, J., Gordon, C., Glowinski, A. J., & O’Neil, M. (1990). Logic engineering for knowledge engineering: The oxford system of medicine. Artificial Intelligence in Medicine, 2, 323–339.

    Article  Google Scholar 

  • Frege, G. (1956). The thought: A logical inquiry. Mind 65(259), 289–311. First published: Der Gedanke (1918–1919).

    Google Scholar 

  • Friedman, N., Halpern, J. Y. (1994). On the complexity of conditional logics. In Proceedings of the 4th International Conference on Principles of Knowledge Representation and Reasoning (KR-94) (pp. 202–213). Morgan Kaufmann.

  • Huth, M., & Mark, R. (2004). Logic in computer science modelling and reasoning about systems (2nd ed.). Cambridge: Cambridge University Press.

    Book  Google Scholar 

  • Lewis, D. K. (1973). Counterfactuals. Cambridge, Massachusetts: Harvard University Press.

    Google Scholar 

  • Lycan, W. G. (2001). Real conditionals. Oxford: Oxford University Press.

    Google Scholar 

  • Makinson, D. C. (1993). Five faces of minimality. Studia Logica, 52, 339–379.

    Article  Google Scholar 

  • Olivetti, N., Schwind, C. (2001). A calculus and complexity bound for minimal conditional logic. In A. Restivo, S. R. D. Rocca & L. Roversi (Eds.), ICTCS (Vol. 2202, pp. 384–404). Lecture notes in computer science, Springer.

  • Shapiro, S. (2009). Classical logic. In E. N. Zalta (Ed.), The stanford encyclopedia of philosophy, winter 2009 edn. http://plato.stanford.edu/archives/win2009/entries/logic-classical/.

  • Stalnaker, R. C. (1968). A theory of conditionals. In N. Rescher (Ed.), Studies in logical theory (pp. 98–112). Oxford: Basil Blackwell.

    Google Scholar 

  • Vidal, M. (2012). Conditionnels et connexions. Ph.D. dissertation, Institut Jean Nicod, E.H.E.S.S., Paris. Available on request.

  • Wansing, H. (2010). Connexive logic. In E. N. Zalta (Ed.), The stanford encyclopedia of philosophy. Stanford University. http://plato.stanford.edu/entries/logic-connexive/.

Download references

Acknowledgments

I would like to thank three anonymous referees for valuable comments on an earlier version of this paper.

Author information

Authors and Affiliations

Authors

Corresponding author

Correspondence to Mathieu Vidal.

Appendices

Appendix 1

In this appendix, I present the beginning of the source code of a typical class of test employed during my research. It is based on the Junit library, a framework specialized for testing purpose in a Java environment. I first detail the most important sections before grouping the different elements together. These explanations assume a basic understanding of object-oriented programming techniques.

Let us first look at the declaration of the class. Its name (“SufficientConnectionTransitiveTest”) is chosen to indicate its function. The first chunk of the identifier (“SufficientConnection”) details the type of hypothetical sentence that will be tested. The second part (“Transitive”) specifies that the context is constant, allowing the validity of transitive inferences. Finally, the last segment (“Test”) describes the general purpose of the class. The most important point is that the class must extend the basic class TestCase to benefit from the capabilities of the Junit framework. Indeed, TestCase allows running multiple tests.

public class SufficientConnectionTransitiveTest extends TestCase {

The next part of the code concerns the declaration of the main attribute of the class. Its name is validator, with a lower-case first letter. Its class is Validator (“V” capital letter), a class designed in my software to test the validity of inferences. Finally, the object is created with the constructor Validator(boolean) preceded by the reserved word new. When the boolean is true, we have a constant context (validation of the transitivity) and when the boolean is false, we obtain a changing context (invalidation of the transitivity).

private Validator validator = new Validator(true);

The third interesting part of the code is the way we test a particular inference. To do it, we pass the string representing the reasoning to test to the method validateDeduction of the validator. The result is obtained via the call to the method isResult. Hence, validator.validateDeduction(“\((p \rightarrow q) \wedge p \vdash q\)”)).isResult() returns true if the modus ponens is valid, false otherwise. Finally, this call is used as the second argument of the method assertEquals from Junit. Its first argument is the expected result, before the test is passed. Hence, the method assertEquals signals an error if the two booleans are divergent: we obtained a result different from the initial prediction.

assertEquals(true, validator.validateDeduction (“\((p \rightarrow q) \wedge p \vdash q\)”)).isResult());

Finally, below are the different elements put together. “...” indicates a missing part of the code, not sufficiently interesting to be reproduced here. Comments are the text between “/**” and “*/” or lines beginning with “//”. Notice that the three first tests are embedded in a method called here “testClassics”. ...

public class SufficientConnectionTransitiveTest extends TestCase {

    /** Object which tests the validity of the inference. */

    private Validator validator = new Validator(true);

/** Test of classical inferences in conditional logic.*/

public void testClassics() throws Exception {

     // Modus Ponens

     assertEquals(true, (validator.

            validateDeduction(“\((p \rightarrow q) \wedge p \vdash q\)”)).isResult());

      // Modus Tollens

     assertEquals(true, (validator.

           validateDeduction(“\((p \rightarrow q) \wedge \lnot q \vdash \lnot p\)”)).isResult());

      // Affirming the Consequent

     assertEquals(false, (validator.

           validateDeduction(“\((p \rightarrow q) \wedge q \vdash p\)”)).isResult());

...

The number of inferences tested can be easily increased, by adding them to the existing method or by grouping them under a different function.

Appendix 2

To execute the test campaign, I use the build manager Maven. The command mvn test launches it by telling to run all the tests defined in the project. Notice that further instructions can be given to Maven, such as to compile the code before the testing. This is useful for instance after a change of the implementation of one connective. Below is the beginning and the end of the outputs produced with this command. As several inferences are grouped in each test, behind the 170 tests are computed around 1,200 inferences.

figure a

We see that four tests fall into error. The intermediate console output (not shown here) displays the name of the failed methods with the line where the problems occur. It allows finding quickly the inferences whose results differ from the initial predictions.

Rights and permissions

Reprints and permissions

About this article

Cite this article

Vidal, M. Speed Up the Conception of Logical Systems with Test-Driven Development. J of Log Lang and Inf 23, 83–103 (2014). https://doi.org/10.1007/s10849-013-9180-x

Download citation

  • Published:

  • Issue Date:

  • DOI: https://doi.org/10.1007/s10849-013-9180-x

Keywords

Navigation