From ba130ecb0ff52e2a9e9743a1e73ace4386ab0e8f Mon Sep 17 00:00:00 2001 From: Glen Whitney Date: Fri, 22 Jan 2021 09:29:57 -0800 Subject: [PATCH] feat: Implement Chapter9 Also provides proper associativity on the operators, to avoid ambiguous parses. This completes all of the examples in the Spoofax Tutorial/Reference that use the propositional signature. --- README.md | 25 +- docrefs/sec6.2.md | 1 + syntax/Spoofax-Propositional-Language.sdf3 | 8 +- test/manual-suite.spt | 262 +++++++++++++++++++-- trans/prop-dnf10.str | 9 + trans/prop-dnf11.str | 6 + trans/prop-dnf4.str | 14 ++ trans/prop-dnf5.str | 12 + trans/prop-dnf6.str | 12 + trans/prop-dnf7.str | 14 ++ trans/prop-dnf8.str | 10 + trans/prop-dnf9.str | 6 + trans/prop-eval-rules.str | 2 +- trans/prop-laws.str | 4 +- trans/sec9_1.str | 18 ++ trans/sec9_2.str | 14 ++ trans/spoofax_propositional_language.str | 10 + 17 files changed, 402 insertions(+), 25 deletions(-) create mode 100644 docrefs/sec6.2.md create mode 100644 trans/prop-dnf10.str create mode 100644 trans/prop-dnf11.str create mode 100644 trans/prop-dnf4.str create mode 100644 trans/prop-dnf5.str create mode 100644 trans/prop-dnf6.str create mode 100644 trans/prop-dnf7.str create mode 100644 trans/prop-dnf8.str create mode 100644 trans/prop-dnf9.str create mode 100644 trans/sec9_1.str create mode 100644 trans/sec9_2.str diff --git a/README.md b/README.md index 602a5a1..3d07474 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,22 @@ Stratego for the first time: Syntax Definition Language SDF3, there does not seem to be any publicly available repository containing the worked examples to follow along with. -This [Gitea repository](https://code.studioinfinity.org/glen/spoofax_prop) aims to fill both gaps. It can be cloned as an Eclipse project (note the git root is at the project level rather than in the directory above the project, as may be more common; in other words, this repository should be cloned within an existing Eclipse workspace, rather than as the workspace itself). Within that project, (ultimately) every example from the Stratego Tutorial manual starting from Section 4 on can be executed directly. And this (Mkdocs-generated) documentation seeks to clarify the ways that Stratego transformations may be run in the Spoofax/Eclipse IDE environment, serving as a supplement/replacement for the portions of the manual that were specific to Stratego/XT. +This [Gitea repository](https://code.studioinfinity.org/glen/spoofax_prop) aims +to fill both gaps. It can be cloned as an Eclipse project (note the git root +is at the project level rather than in the directory above the project, as may +be more common; in other words, this repository should be cloned within +an existing Eclipse workspace, rather than as the workspace itself). Within that +project, all of the examples from the Stratego Tutorial manual that employ the +propositional language (see below), starting from Section 4 on, can be executed +directly. This repository does not attempt to implement the portion of examples +dealing with an arithmetical/imperative language (except in a couple of +isolated instances in which the relevant phenomenon is recast in the +propositional language). + +This (Mkdocs-generated) documentation seeks to clarify the ways that Stratego +transformations may be run in the Spoofax/Eclipse IDE environment, serving as +a supplement/replacement for the portions of the manual that are +specific to Stratego/XT. ## Preliminaries @@ -69,3 +84,11 @@ It consists of the following signature of constructors: Continue reading in the latest released [SPL documentation](http://studioinfinity.org/SPL) to see how to define and run Stratego transformations on ASTs of this language. + +### Building the documentation + +In order to build the documentation from a clone of this repository, you must +install [MkDocs](http://mkdocs.org) and the `semiliterate` plug-in for MkDocs, +which is available in +[pre-release form](https://code.studioinfinity.org/glen/mkdocs-semiliterate). Then +you can execute `mkdocs build` in the top-level directory of this project. diff --git a/docrefs/sec6.2.md b/docrefs/sec6.2.md new file mode 100644 index 0000000..9bda901 --- /dev/null +++ b/docrefs/sec6.2.md @@ -0,0 +1 @@ +[Section 6.2](http://www.metaborg.org/en/latest/source/langdev/meta/lang/stratego/strategoxt/06-rules-and-strategies.html#what-is-a-strategy) diff --git a/syntax/Spoofax-Propositional-Language.sdf3 b/syntax/Spoofax-Propositional-Language.sdf3 index 71bd2f7..8bf0eaa 100644 --- a/syntax/Spoofax-Propositional-Language.sdf3 +++ b/syntax/Spoofax-Propositional-Language.sdf3 @@ -34,10 +34,10 @@ context-free syntax Prop.False = <0> Prop.Atom = String Prop.Not = > - Prop.And = < & > - Prop.Or = < | > - Prop.Impl = [[Prop] -> [Prop]] - Prop.Eq = < = > + Prop.And = < & > {left} + Prop.Or = < | > {left} + Prop.Impl = [[Prop] -> [Prop]] {right} + Prop.Eq = < = > {non-assoc} Prop = <()> {bracket} String = ID diff --git a/test/manual-suite.spt b/test/manual-suite.spt index 3369a53..57a2297 100644 --- a/test/manual-suite.spt +++ b/test/manual-suite.spt @@ -58,19 +58,18 @@ test sec5_1_2_test1_cnf_ex [[ test sec5_1_2_test1_both [[ (r -> p & q) & p -]] run dcnf to Atom("x") -//(Or(And(Not(Atom("r")),Atom("p")),And(And(Atom("p"),Atom("q")),Atom("p"))), -// And(And(Or(Not(Atom("r")), Atom("p")), -// Or(Not(Atom("r")), Atom("q"))), -// Atom("p"))) +]] run dcnf to (Or(And(Not(Atom("r")),Atom("p")),And(And(Atom("p"),Atom("q")),Atom("p"))), + And(And(Or(Not(Atom("r")), Atom("p")), + Or(Not(Atom("r")), Atom("q"))), + Atom("p"))) test sec5_3_1_test1_dnf_ex [[ (r -> p & q) & p -]] run dnf4 to Or(And(Not(Atom("r")),Atom("p")),And(And(Atom("p"),Atom("q")),Atom("p"))) +]] run dnf-laws to Or(And(Not(Atom("r")),Atom("p")),And(And(Atom("p"),Atom("q")),Atom("p"))) test sec5_3_1_test1_cnf_ex [[ (r -> p & q) & p -]] run cnf4 to And(And(Or(Not(Atom("r")), Atom("p")), +]] run cnf-laws to And(And(Or(Not(Atom("r")), Atom("p")), Or(Not(Atom("r")), Atom("q"))), Atom("p")) @@ -110,15 +109,15 @@ To illustrate extending a rule, we need to give the rule we're going to extend a different identifier and add both definitions to that (otherwise our original rule `SwapArgs` would already have been extended). -The `chap6.str` file also includes a solution to the exercise in -[Section 6.2](http://www.metaborg.org/en/latest/source/langdev/meta/lang/stratego/strategoxt/06-rules-and-strategies.html#what-is-a-strategy). -On the other hand, it is not clear whether the Spoofax Eclipse IDE has a "debug" -operator for Stratego, or if so how it would work, so the repository does not +The `chap6.str` file also includes a solution to the exercise +in {! ../docrefs/sec6.2.md !}. On the other hand, it is not clear whether +the Spoofax Eclipse IDE has a "debug" operator for Stratego, or if so how +it would work within the IDE, so the repository does not attempt to implement the "debug" example. The remainder of the chapter (from section 6.3 on) consists of general information about Stratego syntax and information about the Stratego compiler. As it's not -clear if the latter applies to the Spoofax Eclipse IDE, there are no further test +clear whether the latter applies to the Spoofax Eclipse IDE, there are no further test cases in this repository beyond Section 6.2. **/ @@ -152,10 +151,10 @@ test sec6_2_invoke_rule_ex [[ test sec6_2_innermost_ex [[ p = q -]] run dnf4 to Or(Or(And(Not(Atom("p")),Not(Atom("q"))), - And(Not(Atom("p")),Atom("p"))), - Or(And(Atom("q"),Not(Atom("q"))), - And(Atom("q"),Atom("p")))) +]] run dnf-laws to Or(Or(And(Not(Atom("p")),Not(Atom("q"))), + And(Not(Atom("p")),Atom("p"))), + Or(And(Atom("q"),Not(Atom("q"))), + And(Atom("q"),Atom("p")))) test sec6_2_dnf_exercise_ex [[ p = q @@ -199,7 +198,7 @@ test sec7_3_repeat_small_ex [[ ]] run repeatmaybeAB to Impl(True(), False()) test sec7_3_repeat_big_ex [[ - (1 -> (1 -> (1 -> (1 -> 0)))) | 0 + (1 -> 1 -> 1 -> 1 -> 0) | 0 ]] run repeatmaybeAB to Impl(True(), Impl(True(), Impl(True(), Impl(True(), False())))) @@ -236,3 +235,232 @@ test sec8_5_1_wrap_ex [[ test sec8_5_2_project_ex [[ p | !p ]] run TermProj to Atom("p") + +/** md +### Chapter 9 + +This chapter is much more in the style of the early chapters: there are several +explicit Stratego modules, and we incorporate each one into this repository. As +before, we need to differentiate the names in some modules since they all end +up being loaded at once; but we also take advantage of the common sections of +some of the modules and re-use rather than repeat the code. In addition, the +disjunctive and conjunctive normal forms of the same test expression as used +in Chapter Five are used for test cases in `trans/manual-suite.spt`. + +**/ + +test chap9_dnf4_ex [[ + (r -> p & q) & p +]] run dnf4 to Or(And(Not(Atom("r")),Atom("p")),And(And(Atom("p"),Atom("q")),Atom("p"))) + +test chap9_dnf6_ex [[ + (r -> p & q) & p +]] run dnf6 to Or(And(Not(Atom("r")),Atom("p")),And(And(Atom("p"),Atom("q")),Atom("p"))) + +test chap9_dnf7_ex [[ + (r -> p & q) & p +]] run dnf7 to Or(And(Not(Atom("r")),Atom("p")),And(And(Atom("p"),Atom("q")),Atom("p"))) + +test chap9_cnf7_ex [[ + (r -> p & q) & p +]] run cnf7 to And(And(Or(Not(Atom("r")), Atom("p")), + Or(Not(Atom("r")), Atom("q"))), + Atom("p")) + +/** md +The key point to know about +[Chapter 9](http://www.metaborg.org/en/latest/source/langdev/meta/lang/stratego/strategoxt/09-traversal-strategies.html), +however, is that there is a mistake that affects examples `prop-dnf8` through +`prop-dnf10`. The difficulty is in this definition: +```Stratego +strategies + propbu(s) = proptr(propbu(s)); s +``` + +Recall that `proptr` is defined as follows: (Note that our implementation calls +it `proptr7` to distinguish it from different definitions for `proptr` in other +examples.) +```Stratego +{! ../trans/prop-dnf7.str extract: + start: '(rules\n*)' + stop: strategies +!} +``` + +So `propbu` must be defined as: +```Stratego +{! ../trans/prop-dnf8.str extract: + start: strategies + stop: '(.*propbu8.*)' +!} +``` + +The point is that `proptr` cannot apply to `Atom`s and logical constants, and so +fails when it reaches such nodes in the AST. Without the `try` in the definition +of the `propbu` traversal, any such failure propagates to a failure of the entire +strategy. +**/ + +test chap9_dnf8_ex [[ + (r -> p & q) & p +]] run dnf8 to Or(And(Not(Atom("r")),Atom("p")),And(And(Atom("p"),Atom("q")),Atom("p"))) + +test chap9_cnf8_ex [[ + (r -> p & q) & p +]] run cnf8 to And(And(Or(Not(Atom("r")), Atom("p")), + Or(Not(Atom("r")), Atom("q"))), + Atom("p")) + +/** md +Example `prop-dnf9` simply re-uses `propbu8`. +**/ + +test chap9_dnf9_ex [[ + (r -> p & q) & p +]] run dnf9 to Or(And(Not(Atom("r")),Atom("p")),And(And(Atom("p"),Atom("q")),Atom("p"))) + +test chap9_cnf9_ex [[ + (r -> p & q) & p +]] run cnf9 to And(And(Or(Not(Atom("r")), Atom("p")), + Or(Not(Atom("r")), Atom("q"))), + Atom("p")) + +/** md +And a similar fix is made to `prop-dnf10`: +```Stratego +{! ../trans/prop-dnf10.str !} +``` + +**/ + +test sec9_1_dnf10_ex [[ + (r -> p & q) & p +]] run dnf10 to Or(And(Not(Atom("r")),Atom("p")),And(And(Atom("p"),Atom("q")),Atom("p"))) + +test sec9_1_cnf10_ex [[ + (r -> p & q) & p +]] run cnf10 to And(And(Or(Not(Atom("r")), Atom("p")), + Or(Not(Atom("r")), Atom("q"))), + Atom("p")) + +/** md +There is another issue in the "Format Checking" example in section 9.1. It lies +with the strategy used to determine if an expression is an atom or the negation +of an atom. The expression shown is `Not(Atom(x)) <+ Atom(x)`. This appears to +be a left choice of two congruences. But a congruence expects a strategy as an +argument, whereas here `x` is simply a free variable. There are a couple of +fixes to write an expression that checks whether a term is just an `Atom()` call +or the negation of one. The first possibility is to use match expressions, e.g. +`?Not(Atom(x)) <+ ?Atom(x)`. However, as that can run into issues with the scoping +of the variable `x`, we opted for sticking with the congruences, just using a +strategy that always succeeds in the inner position, namely `id`: +```Stratego +{! ../trans/sec9_1.str terminate: exercise !} +``` +**/ + +test sec9_1_disj-nf_fails [[ + (r -> p & q) & p +]] run disj-nf fails + +test sec9_1_conj-nf_fails [[ + (r -> p & q) & p +]] run conj-nf fails + +test sec9_1_disj-nf [[ + (!r & p) | (p & q & p) +]] run disj-nf + +test sec9_1_conj-nf [[ + (!r | p) & (!r | q) & p +]] run conj-nf + +test sec9_1_dnf11_ex [[ + (r -> p & q) & p +]] run dnf11 to Or(And(Not(Atom("r")),Atom("p")),And(And(Atom("p"),Atom("q")),Atom("p"))) + +test sec9_1_cnf11_ex [[ + (r -> p & q) & p +]] run cnf11 to And(And(Or(Not(Atom("r")), Atom("p")), + Or(Not(Atom("r")), Atom("q"))), + Atom("p")) + +/** md +Also note that the repository does not include `prop-dnf12` because at this +point the strategies there have become identical to the ones +in {! ../docrefs/sec6.2.md !} used to introduce the idea of splitting +transformations into local rewrite rules applied via a traversal strategy. So +they have already been implemented and tested above. + +On the other hand, in `trans/sec9_1.str`, the repository does contain a +solution for the second exercise in +[Section 9.1.2](http://www.metaborg.org/en/latest/source/langdev/meta/lang/stratego/strategoxt/09-traversal-strategies.html#visiting-one-subterm). +**/ + +test sec9_1_2_second_exercise_inner_ex [[ + !!p | (!!q | r) +]] run inner-soln to Or(Atom("p"), Or(Atom("q"), Atom("r"))) + +test sec9_1_2_second_exercise_outer_ex [[ + !!p | (!!q | r) +]] run outer-soln to Impl(Not(Atom("p")), Impl(Not(Atom("q")), Atom("r"))) + +/* Note that the actual output of the following test matches + the inner application. However, according to the manual, it would + also be a correct implementation for it to produce + `Impl(Not(Atom("p")), Or(Atom("q"), Atom("r")))`, which could not + result from either outer or inner application. +*/ +test sec9_1_2_second_exercise_random_ex [[ + !!p | (!!q | r) +]] run random-soln to Atom("x") + +test sec9_2_eval_bottomup_ex [[ + 1 & !(0 | 1) +]] run eval1 to False() + +/* This test fails deliberately, to show that topdown evaluation + does not go all the way to completion. +*/ +test sec9_2_eval_topdown [[ + 1 & !(0 | 1) +]] run eval2 to False() + +test sec9_2_eval_exercise_bottomup_ex [[ + (1 | 0) & (0 | 1) +]] run eval1 to True() + +/* Ditto for this one.*/ +test sec9_2_eval_exercise_topdown [[ + (1 | 0) & (0 | 1) +]] run eval2 to True() + +test sec9_2_desugar_topdown_ex [[ + p = q +]] run desugar to And(Or(Not(Atom("p")),Atom("q")),Or(Not(Atom("q")),Atom("p"))) + +/* And ditto for this one. */ +test sec9_2_desugar_bottomup [[ + p = q +]] run desugar2 to And(Or(Not(Atom("p")),Atom("q")),Or(Not(Atom("q")),Atom("p"))) + +test sec9_2_impl-nf_repeated_ex [[ + p & q +]] run impl-nf1 to Impl(Impl(Atom("p"),Impl(Atom("q"),False())),False()) + +/* And ditto for this one. */ +test sec9_2_impl-nf_once [[ + p & q +]] run impl-nf2 to Impl(Impl(Atom("p"),Impl(Atom("q"),False())),False()) + +/** md +I couldn't think of a natural application of paramorphism in the context of +the Spoofax Propositional Language, so there is no solution provided for the +exercise just before +[Section 9.2.1](http://www.metaborg.org/en/latest/source/langdev/meta/lang/stratego/strategoxt/09-traversal-strategies.html#cascading-transformations). + +The rest of Chapter 9 and all of the remaining chapters deal +either with signatures other than SPL or +just with abstract principles, so that concludes the Stratego examples provided +in this repository. +**/ diff --git a/trans/prop-dnf10.str b/trans/prop-dnf10.str new file mode 100644 index 0000000..b9a0915 --- /dev/null +++ b/trans/prop-dnf10.str @@ -0,0 +1,9 @@ +module prop-dnf10 +imports libstrategolib signatures/- prop-laws + +strategies + proptr10(s) = Not(s) <+ And(s, s) <+ Or(s, s) <+ Impl(s, s) <+ Eq(s, s) + propbu10(s) = try(proptr10(propbu10(s))); s +strategies + dnf10 = propbu10(try(DN <+ (DefI <+ DefE <+ DMA <+ DMO <+ DAOL <+ DAOR); dnf10)) + cnf10 = propbu10(try(DN <+ (DefI <+ DefE <+ DMA <+ DMO <+ DOAL <+ DOAR); cnf10)) diff --git a/trans/prop-dnf11.str b/trans/prop-dnf11.str new file mode 100644 index 0000000..9d073ad --- /dev/null +++ b/trans/prop-dnf11.str @@ -0,0 +1,6 @@ +module prop-dnf11 +imports libstrategolib prop-laws + +strategies + dnf11 = bottomup(try(DN <+ (DefI <+ DefE <+ DMA <+ DMO <+ DAOL <+ DAOR); dnf11)) + cnf11 = bottomup(try(DN <+ (DefI <+ DefE <+ DMA <+ DMO <+ DOAL <+ DOAR); cnf11)) diff --git a/trans/prop-dnf4.str b/trans/prop-dnf4.str new file mode 100644 index 0000000..6e996aa --- /dev/null +++ b/trans/prop-dnf4.str @@ -0,0 +1,14 @@ +module prop-dnf4 +imports libstrategolib prop-laws + +rules + dnf4 : True() -> True() + dnf4 : False() -> False() + dnf4 : Atom(x) -> Atom(x) + dnf4 : Not(x) -> Not (x) + dnf4 : And(x, y) -> And (x, y) + dnf4 : Or(x, y) -> Or (x, y) + dnf4 : Impl(x, y) -> Impl(x, y) + dnf4 : Eq(x, y) -> Eq (x, y) +strategies + dnfred4 = try(DN <+ (DefI <+ DefE <+ DMA <+ DMO <+ DAOL <+ DAOR); dnf4) diff --git a/trans/prop-dnf5.str b/trans/prop-dnf5.str new file mode 100644 index 0000000..e1647a8 --- /dev/null +++ b/trans/prop-dnf5.str @@ -0,0 +1,12 @@ +module prop-dnf5 +imports libstrategolib prop-laws + +rules + dnft5 : Not(x) -> Not (x) + dnft5 : And(x, y) -> And (x, y) + dnft5 : Or(x, y) -> Or (x, y) + dnft5 : Impl(x, y) -> Impl(x, y) + dnft5 : Eq(x, y) -> Eq (x, y) +strategies + dnf5 = try(dnft5) + dnfred5 = try(DN <+ (DefI <+ DefE <+ DMA <+ DMO <+ DAOL <+ DAOR); dnf5) diff --git a/trans/prop-dnf6.str b/trans/prop-dnf6.str new file mode 100644 index 0000000..80b5c61 --- /dev/null +++ b/trans/prop-dnf6.str @@ -0,0 +1,12 @@ +module prop-dnf6 +imports libstrategolib prop-laws + +rules + dnft6 : Not(x) -> Not (x) + dnft6 : And(x, y) -> And (x, y) + dnft6 : Or(x, y) -> Or (x, y) + dnft6 : Impl(x, y) -> Impl(x, y) + dnft6 : Eq(x, y) -> Eq (x, y) +strategies + dnf6 = try(dnft6); dnfred6 + dnfred6 = try(DN <+ (DefI <+ DefE <+ DMA <+ DMO <+ DAOL <+ DAOR); dnf6) \ No newline at end of file diff --git a/trans/prop-dnf7.str b/trans/prop-dnf7.str new file mode 100644 index 0000000..ac5c995 --- /dev/null +++ b/trans/prop-dnf7.str @@ -0,0 +1,14 @@ +module prop-dnf7 +imports libstrategolib prop-laws + +rules + proptr7(s) : Not(x) -> Not (x) + proptr7(s) : And(x, y) -> And (x, y) + proptr7(s) : Or(x, y) -> Or (x, y) + proptr7(s) : Impl(x, y) -> Impl(x, y) + proptr7(s) : Eq(x, y) -> Eq (x, y) +strategies + dnf7 = try(proptr7(dnf7)); dnfred7 + dnfred7 = try(DN <+ (DefI <+ DefE <+ DMA <+ DMO <+ DAOL <+ DAOR); dnf7) + cnf7 = try(proptr7(cnf7)); cnfred7 + cnfred7 = try(DN <+ (DefI <+ DefE <+ DMA <+ DMO <+ DOAL <+ DOAR); cnf7) diff --git a/trans/prop-dnf8.str b/trans/prop-dnf8.str new file mode 100644 index 0000000..48b0fc7 --- /dev/null +++ b/trans/prop-dnf8.str @@ -0,0 +1,10 @@ +module prop-dnf8 +imports libstrategolib prop-laws prop-dnf7 + +strategies + propbu8(s) = try(proptr7(propbu8(s))); s +strategies + dnf8 = propbu8(dnfred8) + dnfred8 = try(DN <+ (DefI <+ DefE <+ DMA <+ DMO <+ DAOL <+ DAOR); dnf8) + cnf8 = propbu8(cnfred8) + cnfred8 = try(DN <+ (DefI <+ DefE <+ DMA <+ DMO <+ DOAL <+ DOAR); cnf8) diff --git a/trans/prop-dnf9.str b/trans/prop-dnf9.str new file mode 100644 index 0000000..e1f1d2a --- /dev/null +++ b/trans/prop-dnf9.str @@ -0,0 +1,6 @@ +module prop-dnf9 +imports libstrategolib prop-laws prop-dnf8 + +strategies + dnf9 = propbu8(try(DN <+ (DefI <+ DefE <+ DMA <+ DMO <+ DAOL <+ DAOR); dnf9)) + cnf9 = propbu8(try(DN <+ (DefI <+ DefE <+ DMA <+ DMO <+ DOAL <+ DOAR); cnf9)) \ No newline at end of file diff --git a/trans/prop-eval-rules.str b/trans/prop-eval-rules.str index 5ee5638..d5da8cc 100644 --- a/trans/prop-eval-rules.str +++ b/trans/prop-eval-rules.str @@ -82,7 +82,7 @@ included into the `editor/Main.esv` file, like so: replace: ['^\s*$'] terminate: 'provider\s*:' !} [ ... rest of file suppressed for brevity. ] ``` -It's just the one line `Manual` in the `imports` section that we have added. The +It's just the one line "Manual" in the `imports` section that we have added. The `editor/Manual.esv` implementing the submenu is also very simple: ```esv {! ../editor/Manual.esv terminate: dnf !} diff --git a/trans/prop-laws.str b/trans/prop-laws.str index 570f8ba..51a6de0 100644 --- a/trans/prop-laws.str +++ b/trans/prop-laws.str @@ -18,5 +18,5 @@ rules strategies - dnf4 = innermost(DefI <+ DefE <+ DAOL <+ DAOR <+ DN <+ DMA <+ DMO) - cnf4 = innermost(DefI <+ DefE <+ DOAL <+ DOAR <+ DN <+ DMA <+ DMO) + dnf-laws = innermost(DefI <+ DefE <+ DAOL <+ DAOR <+ DN <+ DMA <+ DMO) + cnf-laws = innermost(DefI <+ DefE <+ DOAL <+ DOAR <+ DN <+ DMA <+ DMO) diff --git a/trans/sec9_1.str b/trans/sec9_1.str new file mode 100644 index 0000000..e103371 --- /dev/null +++ b/trans/sec9_1.str @@ -0,0 +1,18 @@ +module sec9_1 +imports libstrategolib signatures/- prop-laws prop-desugar + +strategies + conj(s) = And(conj(s), conj(s)) <+ s + disj(s) = Or (disj(s), disj(s)) <+ s + + // Conjunctive normal form + conj-nf = conj(disj(Not(Atom(id)) <+ Atom(id))) + + // Disjunctive normal form + disj-nf = disj(conj(Not(Atom(id)) <+ Atom(id))) + + // Second exercise, Section 9.1.2 + path-dep-xform = DN <+ IDefI + inner-soln = repeat(oncebu(path-dep-xform)) + outer-soln = repeat(oncetd(path-dep-xform)) + random-soln = repeat(rec x(one(x) + path-dep-xform)) diff --git a/trans/sec9_2.str b/trans/sec9_2.str new file mode 100644 index 0000000..6b8c109 --- /dev/null +++ b/trans/sec9_2.str @@ -0,0 +1,14 @@ +module sec9_2 +imports prop-eval2 prop-desugar + +rules + DefT : True() -> Impl(False(), False()) + +strategies + eval1 = bottomup(try(Eval)) + eval2 = topdown(try(Eval)) + + desugar2 = bottomup(try(DefI <+ DefE)) + + impl-nf1 = topdown(repeat(DefT <+ DefN <+ DefA2 <+ DefO1 <+ DefE)) + impl-nf2 = topdown(try(DefT <+ DefN <+ DefA2 <+ DefO1 <+ DefE)) diff --git a/trans/spoofax_propositional_language.str b/trans/spoofax_propositional_language.str index a1ea266..c2af7b3 100644 --- a/trans/spoofax_propositional_language.str +++ b/trans/spoofax_propositional_language.str @@ -16,6 +16,16 @@ imports chap6 chap7 chap8 + prop-dnf4 + prop-dnf5 + prop-dnf6 + prop-dnf7 + prop-dnf8 + prop-dnf9 + prop-dnf10 + sec9_1 + prop-dnf11 + sec9_2 rules // Debugging