Skip to content

Commit 7977671

Browse files
MirceaSgithub-actions
andauthored
modified matchEquation to accept new equation format (#2688)
* modified matchEquation to accept new equation format * Format with fourmolu * updated tests and documentation to support new equation format * Added back tests that exercise the old equation format Co-authored-by: github-actions <[email protected]>
1 parent 9247a96 commit 7977671

File tree

4 files changed

+226
-16
lines changed

4 files changed

+226
-16
lines changed

design-decisions/2020-05-02-function-rules.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ rule fun(φ₁ᵢ({Y}), φ₂ᵢ({Y}), ...) => ψᵢ({Y}) requires Preᵢ({Y}) e
3232
Each rule is interpreted in Kore as an axiom,
3333

3434
```.kore
35-
axiom \implies(Preᵢ({Y}), (fun(φ₁ᵢ({Y}), φ₂ᵢ({Y}), ...) = ψᵢ({Y})) ∧ Postᵢ({Y})).
35+
axiom \implies(Preᵢ({Y}), (fun(φ₁ᵢ({Y}), φ₂ᵢ({Y}), ...) = (ψᵢ({Y}) ∧ Postᵢ({Y})))).
3636
```
3737

3838
## Problems
@@ -82,8 +82,8 @@ rule fun(B) => C
8282
which is interpreted in Kore as two axioms,
8383

8484
```.kore
85-
axiom \implies(\top, (fun(A) = C) ∧ \top)
86-
axiom \implies(\top, (fun(B) = C) ∧ \top).
85+
axiom \implies(\top, (fun(A) = (C ∧ \top)))
86+
axiom \implies(\top, (fun(B) = (C ∧ \top))).
8787
```
8888

8989
The K language offers a shorthand notation,
@@ -96,7 +96,7 @@ which is intended to be equivalent to the pair of rules above.
9696
Under the current interpretation, this rule produces an axiom,
9797

9898
```.kore
99-
axiom \implies(\top, (fun(A ∨ B) = C) ∧ \top)
99+
axiom \implies(\top, (fun(A ∨ B) = (C ∧ \top)))
100100
```
101101

102102
which is **not** equivalent to the first interpretation.
@@ -126,7 +126,7 @@ rule fun(φ₁ᵢ({Y}), φ₂ᵢ({Y}), ...) => ψᵢ({Y}) requires Preᵢ({Y}) e
126126
will be interpreted in Kore as
127127

128128
```.kore
129-
axiom \implies(Preᵢ({Y}) ∧ Argsᵢ({X}, {Y}) ∧ Prioᵢ({X}), (fun(X₁, X₂, ...) = ψᵢ({Y})) ∧ Postᵢ({Y}))
129+
axiom \implies(Preᵢ({Y}) ∧ Argsᵢ({X}, {Y}) ∧ Prioᵢ({X}), (fun(X₁, X₂, ...) = (ψᵢ({Y}) ∧ Postᵢ({Y}))))
130130
```
131131

132132
where
@@ -216,8 +216,8 @@ axiom
216216
true = notBool(<=Int(L, X)),
217217
(X₁ ∈ L) ∧ (X₂ ∈ X)
218218
),
219-
\and(
220-
_<=_<_(X₁, X₂, X₃) = false,
219+
_<=_<_(X₁, X₂, X₃) = \and (
220+
false,
221221
\top
222222
)
223223
)
@@ -232,8 +232,8 @@ axiom
232232
(X₁ ∈ L) ∧ (X₂ ∈ X)
233233
)
234234
),
235-
\and(
236-
_<=_<_(X₁, X₂, X₃) = false,
235+
_<=_<_(X₁, X₂, X₃) = \and(
236+
false,
237237
\top
238238
)
239239
)
@@ -255,8 +255,8 @@ axiom
255255
)
256256
)
257257
),
258-
\and(
259-
_<=_<_(X₁, X₂, X₃) = true,
258+
_<=_<_(X₁, X₂, X₃) = \and(
259+
true,
260260
\top
261261
)
262262
)

kore/src/Kore/Equation/Equation.hs

Lines changed: 68 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ module Kore.Equation.Equation (
66
Equation (..),
77
mkEquation,
88
toTermLike,
9+
toTermLikeOld,
910
mapVariables,
1011
refreshVariables,
1112
isSimplificationRule,
@@ -162,12 +163,13 @@ instance InternalVariable variable => Substitute (Equation variable) where
162163
rename = substitute . fmap mkVar
163164
{-# INLINE rename #-}
164165

165-
toTermLike ::
166+
-- This function must be removed as part of https://github.com/kframework/kore/issues/2593
167+
toTermLikeOld ::
166168
InternalVariable variable =>
167169
Sort ->
168170
Equation variable ->
169171
TermLike variable
170-
toTermLike sort equation
172+
toTermLikeOld sort equation
171173
-- \ceil axiom
172174
| isTop requires
173175
, isTop ensures
@@ -228,6 +230,70 @@ toTermLike sort equation
228230
, ensures
229231
} = equation
230232

233+
toTermLike ::
234+
InternalVariable variable =>
235+
Sort ->
236+
Equation variable ->
237+
TermLike variable
238+
toTermLike sort equation
239+
-- \ceil axiom
240+
| isTop requires
241+
, isTop ensures
242+
, TermLike.Ceil_ _ sort1 _ <- left
243+
, TermLike.Top_ sort2 <- right
244+
, sort1 == sort2 =
245+
left
246+
-- function rule
247+
| Just argument' <- argument
248+
, Just antiLeft' <- antiLeft =
249+
let antiLeftTerm = fromPredicate sort antiLeft'
250+
argumentTerm = fromPredicate sort argument'
251+
in TermLike.mkImplies
252+
( TermLike.mkAnd
253+
antiLeftTerm
254+
( TermLike.mkAnd
255+
requires'
256+
argumentTerm
257+
)
258+
)
259+
( TermLike.mkEquals sort left $
260+
TermLike.mkAnd right ensures'
261+
)
262+
-- function rule without priority
263+
| Just argument' <- argument =
264+
let argumentTerm = fromPredicate sort argument'
265+
in TermLike.mkImplies
266+
( TermLike.mkAnd
267+
requires'
268+
(TermLike.mkAnd argumentTerm $ TermLike.mkTop sort)
269+
)
270+
( TermLike.mkEquals sort left $
271+
TermLike.mkAnd right ensures'
272+
)
273+
-- unconditional equation
274+
| isTop requires
275+
, isTop ensures =
276+
TermLike.mkEquals sort left right
277+
-- conditional equation
278+
| otherwise =
279+
TermLike.mkImplies
280+
requires'
281+
( TermLike.mkEquals sort left $
282+
TermLike.mkAnd right ensures'
283+
)
284+
where
285+
requires' = fromPredicate sort requires
286+
ensures' = fromPredicate rightSort ensures
287+
Equation
288+
{ requires
289+
, argument
290+
, antiLeft
291+
, left
292+
, right
293+
, ensures
294+
} = equation
295+
rightSort = TermLike.termLikeSort right
296+
231297
instance
232298
InternalVariable variable =>
233299
HasFreeVariables (Equation variable) variable

kore/src/Kore/Equation/Sentence.hs

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ matchEquation attributes termLike
116116
isSubsortAxiom = (not . null . getSubsorts . Attribute.subsorts) attributes
117117

118118
-- function rule without priority
119+
-- TODO The pattern match below should be removed after the frontend is updated
120+
-- to use the correct format
119121
match
120122
( TermLike.Implies_
121123
_
@@ -148,8 +150,43 @@ matchEquation attributes termLike
148150
, ensures = ensures'
149151
, attributes
150152
}
153+
match
154+
( TermLike.Implies_
155+
_
156+
( TermLike.And_
157+
_
158+
requires
159+
argument@( TermLike.And_
160+
_
161+
(TermLike.In_ _ _ _ _)
162+
_
163+
)
164+
)
165+
( TermLike.Equals_
166+
_
167+
_
168+
left
169+
(TermLike.And_ _ right ensures)
170+
)
171+
) =
172+
do
173+
requires' <- makePredicate requires & Bifunctor.first RequiresError
174+
argument' <- makePredicate argument & Bifunctor.first ArgumentError
175+
ensures' <- makePredicate ensures & Bifunctor.first EnsuresError
176+
pure
177+
Equation
178+
{ requires = requires'
179+
, argument = Just argument'
180+
, antiLeft = Nothing
181+
, left
182+
, right
183+
, ensures = ensures'
184+
, attributes
185+
}
151186

152187
-- function rule with priority
188+
-- TODO The pattern match below should be removed after the frontend is updated
189+
-- to use the correct format
153190
match
154191
( TermLike.Implies_
155192
_
@@ -183,6 +220,42 @@ matchEquation attributes termLike
183220
, ensures = ensures'
184221
, attributes
185222
}
223+
match
224+
( TermLike.Implies_
225+
_
226+
( TermLike.And_
227+
_
228+
antiLeft
229+
( TermLike.And_
230+
_
231+
requires
232+
argument
233+
)
234+
)
235+
( TermLike.Equals_
236+
_
237+
_
238+
left
239+
(TermLike.And_ _ right ensures)
240+
)
241+
) =
242+
do
243+
requires' <- makePredicate requires & Bifunctor.first RequiresError
244+
argument' <- makePredicate argument & Bifunctor.first ArgumentError
245+
antiLeft' <- makePredicate antiLeft & Bifunctor.first AntiLeftError
246+
ensures' <- makePredicate ensures & Bifunctor.first EnsuresError
247+
pure
248+
Equation
249+
{ requires = requires'
250+
, argument = Just argument'
251+
, antiLeft = Just antiLeft'
252+
, left
253+
, right
254+
, ensures = ensures'
255+
, attributes
256+
}
257+
-- TODO The pattern match below should be removed after the frontend is updated
258+
-- to use the correct format
186259
match
187260
( TermLike.Implies_
188261
_
@@ -206,6 +279,30 @@ matchEquation attributes termLike
206279
, ensures = ensures'
207280
, attributes
208281
}
282+
match
283+
( TermLike.Implies_
284+
_
285+
requires
286+
( TermLike.Equals_
287+
_
288+
_
289+
left
290+
(TermLike.And_ _ right ensures)
291+
)
292+
) =
293+
do
294+
requires' <- makePredicate requires & Bifunctor.first RequiresError
295+
ensures' <- makePredicate ensures & Bifunctor.first EnsuresError
296+
pure
297+
Equation
298+
{ requires = requires'
299+
, argument = Nothing
300+
, antiLeft = Nothing
301+
, left
302+
, right
303+
, ensures = ensures'
304+
, attributes
305+
}
209306
match (TermLike.Equals_ _ _ left right) =
210307
pure
211308
Equation

kore/test/Test/Kore/Equation/Sentence.hs

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,8 @@ test_fromSentenceAxiom =
3030
original = mkEquals sortR left right
3131
equation = mkEquation left right
3232
assertions original equation
33-
, testCase "⌈f(x))⌉ → f(x) = g(x) ∧ ⌈h(x)⌉" $ do
33+
, testCase "⌈f(x))⌉ → f(x) = g(x) ∧ ⌈h(x)⌉ (OLD FORMAT)" $ do
34+
-- This test case must be removed as part of https://github.com/kframework/kore/issues/2593
3435
let requires = mkCeil sortR (Mock.f Mock.a)
3536
ensures = mkCeil sortR (Mock.h Mock.b)
3637
left = Mock.f (mkElemVar Mock.x)
@@ -43,8 +44,9 @@ test_fromSentenceAxiom =
4344
{ requires = wrapPredicate requires
4445
, ensures = wrapPredicate ensures
4546
}
46-
assertions original equation
47-
, testCase "New equation form: ⌈f(x)⌉ ∧ ⌈y ∈ x⌉ → f(y) = g(x) ∧ ⌈h(x)⌉" $ do
47+
assertionsOld original equation
48+
, testCase "New equation form: ⌈f(x)⌉ ∧ ⌈y ∈ x⌉ → f(y) = g(x) ∧ ⌈h(x)⌉ (OLD FORMAT)" $ do
49+
-- This test case must be removed as part of https://github.com/kframework/kore/issues/2593
4850
let requires = mkCeil sortR (Mock.f Mock.a)
4951
ensures = mkCeil sortR (Mock.h Mock.b)
5052
argument = mkIn sortR (mkElemVar Mock.y) (mkElemVar Mock.x)
@@ -61,6 +63,38 @@ test_fromSentenceAxiom =
6163
, argument = Just $ wrapPredicate argument
6264
, ensures = wrapPredicate ensures
6365
}
66+
assertionsOld original equation
67+
, testCase "⌈f(x))⌉ → f(x) = g(x) ∧ ⌈h(x)⌉" $ do
68+
let requires = mkCeil sortR (Mock.f Mock.a)
69+
ensures = mkCeil Mock.testSort (Mock.h Mock.b)
70+
left = Mock.f (mkElemVar Mock.x)
71+
right = Mock.g (mkElemVar Mock.x)
72+
original =
73+
mkImplies requires $
74+
mkEquals sortR left (mkAnd right ensures)
75+
equation =
76+
(mkEquation left right)
77+
{ requires = wrapPredicate requires
78+
, ensures = wrapPredicate ensures
79+
}
80+
assertions original equation
81+
, testCase "New equation form: ⌈f(x)⌉ ∧ ⌈y ∈ x⌉ → f(y) = g(x) ∧ ⌈h(x)⌉" $ do
82+
let requires = mkCeil sortR (Mock.f Mock.a)
83+
ensures = mkCeil Mock.testSort (Mock.h Mock.b)
84+
argument = mkIn sortR (mkElemVar Mock.y) (mkElemVar Mock.x)
85+
argument' =
86+
mkAnd argument (mkTop sortR)
87+
left = Mock.f (mkElemVar Mock.y)
88+
right = Mock.g (mkElemVar Mock.y)
89+
original =
90+
mkImplies (mkAnd requires argument') $
91+
mkEquals sortR left (mkAnd right ensures)
92+
equation =
93+
(mkEquation left right)
94+
{ requires = wrapPredicate requires
95+
, argument = Just $ wrapPredicate argument
96+
, ensures = wrapPredicate ensures
97+
}
6498
assertions original equation
6599
]
66100
where
@@ -78,6 +112,19 @@ test_fromSentenceAxiom =
78112
"Expected original pattern"
79113
original
80114
(toTermLike (termLikeSort original) actual)
115+
-- This function must be removed as part of https://github.com/kframework/kore/issues/2593
116+
assertionsOld ::
117+
HasCallStack =>
118+
TermLike VariableName ->
119+
Equation VariableName ->
120+
Assertion
121+
assertionsOld original equation = do
122+
actual <- expectRight $ test original
123+
assertEqual "Expected equation" equation actual
124+
assertEqual
125+
"Expected original pattern"
126+
original
127+
(toTermLikeOld (termLikeSort original) actual)
81128
test original = fromSentenceAxiom (def, mkAxiom [sortVariableR] original)
82129

83130
varI1, varI2 :: TermLike VariableName

0 commit comments

Comments
 (0)