@@ -12,15 +12,27 @@ object ProofsConverter {
12
12
// TODO: remove unnecessary variables "val s_..." in generated proofs -> need to detect which steps are used later in other steps
13
13
// TODO: generate more realistic variable names
14
14
15
- private def indent (s : String , indent : Int = 2 ): String = s.split(" \n " ).map(" " * indent + _).mkString(" \n " )
16
- private def unindent (s : String , indent : Int = 2 ): String = s.split(" \n " ).map(_.drop(indent)).mkString(" \n " )
17
-
15
+ private def indent (s : String , indent : Int = 2 ): String = s.split(" \n " ).map(s => if s == " " then " " else " " * indent + s).mkString(" \n " )
16
+ private def unindent (s : String , indent : Int = 2 ): String = s.split(" \n " ).map(_.stripPrefix(" " * indent)).mkString(" \n " )
17
+
18
+ /**
19
+ * Converts a Sequent, Formula or Term to a valid Scala/Lisa code
20
+ *
21
+ * @param f formula to convert
22
+ * @return Scala code representing the formula in string format
23
+ */
18
24
private def any2code (a : K .Sequent | K .Formula | K .Term ): String = (a match
19
25
case sq : K .Sequent => asFront(sq)
20
26
case form : K .Formula => asFront(form)
21
27
case term : K .Term => asFront(term)
22
28
).toString.replace(" ⇒" , " ==>" ).replace(" ⇔" , " <=>" )
23
29
30
+ /**
31
+ * Converts a SCProof to a valid Scala/Lisa code using tactics.
32
+ *
33
+ * @param p proof to convert
34
+ * @return Scala code representing the proof in string format
35
+ */
24
36
private def scproof2code (p : K .SCProof ): String = {
25
37
def scproof2codeAux (p : K .SCProof , varPrefix : String = " s" , implicitPremises : Seq [String ] = Seq .empty): String = {
26
38
def scproofstep2code (ps : SCProofStep , stepNum : Int , implicitPremises : Seq [String ], varPrefix : String ): String = {
@@ -91,6 +103,12 @@ object ProofsConverter {
91
103
unindent(scproof2codeAux(p))
92
104
}
93
105
106
+ /**
107
+ * Extracts all formulas from a proof
108
+ *
109
+ * @param proof proof to extract formulas from
110
+ * @return set of formulas
111
+ */
94
112
private def extractFormulasFromProof (proof : K .SCProof ): Set [K .Formula ] =
95
113
proof.steps.foldLeft(Set .empty[K .Formula ])((prev, next) => {
96
114
prev ++ (next match
@@ -103,6 +121,12 @@ object ProofsConverter {
103
121
)
104
122
})
105
123
124
+ /**
125
+ * Extracts all variables, functions, formula variables, predicates and connectors from a set of formulas
126
+ *
127
+ * @param formulas set of formulas to extract variables from
128
+ * @return tuple of sets of variables, functions, formula variables, predicates and connectors
129
+ */
106
130
private def extractVariables (
107
131
formulas : Set [K .Formula ]
108
132
): (Set [K .VariableLabel ], Set [K .SchematicFunctionLabel ], Set [K .VariableFormulaLabel ], Set [K .SchematicPredicateLabel ], Set [K .SchematicConnectorLabel ]) =
@@ -130,6 +154,15 @@ object ProofsConverter {
130
154
)
131
155
})
132
156
157
+ /**
158
+ * Generates a valid Scala/Lisa code to declare variables, functions, formula variables, predicates and connectors
159
+ * used in a set of formulas
160
+ *
161
+ * @param formulas set of formulas to generate variables for
162
+ * @param accessibility accessibility of the variables (e.g. "private")
163
+ *
164
+ * @return Scala code representing the variables in string format
165
+ */
133
166
private def generateVariablesCode (formulas : Set [K .Formula ], accessibility : String ): String =
134
167
val (variableSet, functionSet, formulaVariableSet, predicateSet, connectorSet) = extractVariables(formulas)
135
168
val access = if accessibility != " " then accessibility.strip() + " " else " "
@@ -139,25 +172,60 @@ object ProofsConverter {
139
172
predicateSet.map(p => access + s " val ${p.id} = predicate[ ${p.arity}] " ).toList.sorted ++
140
173
connectorSet.map(c => access + s " val ${c.id} = connector[ ${c.arity}] " ).toList.sorted).mkString(" \n " )
141
174
142
- private def generateVariablesCode (statement : K .Sequent , proof : K .SCProof , accessibility : String = " private" ): String =
143
- generateVariablesCode(extractFormulasFromProof(proof) + K .sequentToFormula(statement), accessibility)
144
-
145
- private def generateTheoremCode (name : String , statement : K .Sequent , proof : K .SCProof ): String = {
175
+ /**
176
+ * Generates a valid Scala/Lisa code to declare variables, functions, formula variables, predicates and connectors
177
+ * used in a proof
178
+ *
179
+ * @param proof proof to generate variables for
180
+ * @param accessibility accessibility of the variables (e.g. "private")
181
+ *
182
+ * @return Scala code representing the variables in string format
183
+ */
184
+ private def generateVariablesCode (proof : K .SCProof , accessibility : String = " private" ): String =
185
+ generateVariablesCode(extractFormulasFromProof(proof), accessibility)
186
+
187
+ /**
188
+ * Generates a valid Scala/Lisa code of a theorem and its proof
189
+ *
190
+ * @param name name of the theorem
191
+ * @param proof proof of the theorem
192
+ *
193
+ * @return Scala code representing the theorem in string format
194
+ */
195
+ private def generateTheoremCode (name : String , proof : K .SCProof ): String = {
146
196
s " val $name = Theorem( \n " +
147
- indent(any2code(statement )) +
197
+ indent(any2code(proof.conclusion )) +
148
198
s " \n ) { \n " +
149
199
indent(scproof2code(proof)) +
150
200
s " \n } "
151
201
}
152
202
153
- def generateStandaloneTheoremFileContent (name : String , statement : K .Sequent , proof : K .SCProof ): String =
203
+ /**
204
+ * Generates a valid Scala/Lisa code of a theorem and its proof in a standalone file, including the necessary variables declarations.
205
+ * The theorem and its proof must be self-contained, i.e. no dependencies to other theorems, axioms, definitions, etc.
206
+ *
207
+ * @param name name of the theorem
208
+ * @param proof proof of the theorem
209
+ *
210
+ * @return Scala code representing the theorem in string format
211
+ */
212
+ def generateStandaloneTheoremFileContent (name : String , proof : K .SCProof ): String =
154
213
val camelName = " [A-Za-z0-9]+" .r.findAllIn(name).map(_.capitalize).mkString
155
214
s " object $camelName extends lisa.Main { \n\n " +
156
215
indent(
157
- generateVariablesCode(statement, proof) +
216
+ generateVariablesCode(proof) +
158
217
" \n\n " +
159
- generateTheoremCode(name, statement, proof)
218
+ generateTheoremCode(name, proof)
160
219
) +
161
220
" \n }"
162
221
222
+ /**
223
+ * Parse and check that a generated theorem file is valid, i.e. that it compiles and the theorem is proven
224
+ * @param fileContent content of the generated file
225
+ * @return true if the file is valid, false otherwise
226
+ */
227
+ def checkGeneratedFileContent (fileContent : String ): Boolean =
228
+ // TODO
229
+ false
230
+
163
231
}
0 commit comments