Skip to content

Commit a54e209

Browse files
authored
Isabelle/HOL translation: fix creation of polymorphic records (#3051)
* Creation of polymorphic records was not translated correctly, with the types appearing as arguments instead of the values. * Depends on #3050
1 parent 3dc1789 commit a54e209

File tree

4 files changed

+116
-33
lines changed

4 files changed

+116
-33
lines changed

src/Juvix/Compiler/Backend/Isabelle/Translation/FromTyped.hs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,11 @@ goModule onlyTypes infoTable Internal.Module {..} =
471471

472472
goRecordFields :: [Internal.FunctionParameter] -> [a] -> [(Name, a)]
473473
goRecordFields argtys args = case (argtys, args) of
474-
(ty : argtys', arg' : args') -> (fromMaybe (defaultName (getLoc ty) "_") (ty ^. Internal.paramName), arg') : goRecordFields argtys' args'
474+
(param : argtys', arg' : args')
475+
| param ^. Internal.paramImplicit == Internal.Explicit ->
476+
(fromMaybe (defaultName (getLoc param) "_") (param ^. Internal.paramName), arg') : goRecordFields argtys' args'
477+
| otherwise ->
478+
goRecordFields argtys' args'
475479
_ -> []
476480

477481
goExpression' :: Internal.Expression -> Expression
@@ -567,6 +571,8 @@ goModule onlyTypes infoTable Internal.Module {..} =
567571
fn' <- goExpression fn
568572
args' <- mapM goExpression args
569573
return $ mkApp fn' args'
574+
| _appImplicit /= Internal.Explicit =
575+
goExpression _appLeft
570576
| otherwise = do
571577
l <- goExpression _appLeft
572578
r <- goExpression _appRight
@@ -729,7 +735,7 @@ goModule onlyTypes infoTable Internal.Module {..} =
729735
_ -> Nothing
730736
_ -> Nothing
731737
where
732-
(fn, args) = Internal.unfoldApplication app
738+
(fn, args) = Internal.unfoldExplicitApplication app
733739

734740
getRecordUpdate :: Internal.Application -> Maybe (Name, [Name], Internal.Expression, [(Name, Internal.Expression)])
735741
getRecordUpdate Internal.Application {..} = case _appLeft of
@@ -752,7 +758,7 @@ goModule onlyTypes infoTable Internal.Module {..} =
752758
_ -> Nothing
753759
_ -> Nothing
754760
where
755-
(fn, args) = Internal.unfoldApplication app
761+
(fn, args) = Internal.unfoldExplicitApplication app
756762
_ -> Nothing
757763
_ -> Nothing
758764
_ -> Nothing
@@ -799,7 +805,11 @@ goModule onlyTypes infoTable Internal.Module {..} =
799805

800806
goLet :: Internal.Let -> Sem r Expression
801807
goLet Internal.Let {..} = do
802-
let fdefs = concatMap toFunDefs (toList _letClauses)
808+
let fdefs =
809+
filter (not . Internal.isTypeConstructor . (^. Internal.funDefType))
810+
. concatMap toFunDefs
811+
. toList
812+
$ _letClauses
803813
cls <- mapM goFunDef fdefs
804814
let ns = zipExact (map (^. Internal.funDefName) fdefs) (map (^. letClauseName) cls)
805815
expr <- localNames ns $ goExpression _letExpression

src/Juvix/Compiler/Internal/Extra/Base.hs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,15 @@ unfoldExpressionApp = swap . run . runAccumListReverse . go
460460
unfoldApplication :: Application -> (Expression, NonEmpty Expression)
461461
unfoldApplication = fmap (fmap (^. appArg)) . unfoldApplication'
462462

463+
unfoldExplicitApplication :: Application -> (Expression, [Expression])
464+
unfoldExplicitApplication =
465+
fmap
466+
( fmap (^. appArg)
467+
. filter (\x -> x ^. appArgIsImplicit == Explicit)
468+
. toList
469+
)
470+
. unfoldApplication'
471+
463472
-- | A fold over all transitive children, including self
464473
patternCosmos :: SimpleFold Pattern Pattern
465474
patternCosmos f p = case p of

tests/positive/Isabelle/Program.juvix

Lines changed: 56 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -204,50 +204,45 @@ nf (n1 n2 : Int) : Bool := n1 - n2 >= n1 || n2 <= n1 + n2;
204204

205205
-- Nested record patterns
206206

207-
type MessagePacket (MessageType : Type) : Type := mkMessagePacket {
208-
target : Nat;
209-
mailbox : Maybe Nat;
210-
message : MessageType;
211-
};
207+
type MessagePacket (MessageType : Type) : Type :=
208+
mkMessagePacket {
209+
target : Nat;
210+
mailbox : Maybe Nat;
211+
message : MessageType
212+
};
212213

213214
open MessagePacket;
214215

215216
type EnvelopedMessage (MessageType : Type) : Type :=
216217
mkEnvelopedMessage {
217218
sender : Maybe Nat;
218-
packet : MessagePacket MessageType;
219+
packet : MessagePacket MessageType
219220
};
220221

221222
open EnvelopedMessage;
222223

223-
type Timer (HandleType : Type): Type := mkTimer {
224-
time : Nat;
225-
handle : HandleType;
226-
};
224+
type Timer (HandleType : Type) : Type :=
225+
mkTimer {
226+
time : Nat;
227+
handle : HandleType
228+
};
227229

228230
type Trigger (MessageType : Type) (HandleType : Type) :=
229-
| MessageArrived { envelope : EnvelopedMessage MessageType; }
230-
| Elapsed { timers : List (Timer HandleType) };
231+
| MessageArrived {envelope : EnvelopedMessage MessageType}
232+
| Elapsed {timers : List (Timer HandleType)};
231233

232234
open Trigger;
233235

234236
getMessageFromTrigger : {M H : Type} -> Trigger M H -> Maybe M
235-
| (MessageArrived@{
236-
envelope := (mkEnvelopedMessage@{
237-
packet := (mkMessagePacket@{
238-
message := m })})})
239-
:= just m
240-
| _ := nothing;
241-
237+
| MessageArrived@{envelope := mkEnvelopedMessage@{packet := mkMessagePacket@{message := m}}} :=
238+
just m
239+
| _ := nothing;
242240

243241
getMessageFromTrigger' {M H} (t : Trigger M H) : Maybe M :=
244-
case t of
245-
| (MessageArrived@{
246-
envelope := (mkEnvelopedMessage@{
247-
packet := (mkMessagePacket@{
248-
message := m })})})
249-
:= just m
250-
| _ := nothing;
242+
case t of
243+
| MessageArrived@{envelope := mkEnvelopedMessage@{packet := mkMessagePacket@{message := m}}} :=
244+
just m
245+
| _ := nothing;
251246

252247
-- Syntax aliases
253248

@@ -259,6 +254,38 @@ idT (x : T) : T := x;
259254

260255
t : T := 0;
261256

262-
type RR := mkRR {
263-
x : T
264-
};
257+
type RR := mkRR {x : T};
258+
259+
-- Type constructor identifiers
260+
261+
type GuardOutput (A L X : Type) :=
262+
mkGuardOutput {
263+
args : List A;
264+
label : L;
265+
other : X
266+
};
267+
268+
open GuardOutput;
269+
270+
type GuardReturnLabel :=
271+
| doIncrement
272+
| doRespond Nat;
273+
274+
open GuardReturnLabel;
275+
276+
type GuardReturnOther := nuthing;
277+
278+
open GuardReturnOther;
279+
280+
type GuardReturnArgs := ReplyTo Nat;
281+
282+
ifIncrement
283+
: Trigger Nat Nat -> Maybe (GuardOutput GuardReturnArgs GuardReturnLabel GuardReturnOther)
284+
| MessageArrived@{envelope := m} :=
285+
just
286+
mkGuardOutput@{
287+
args := [];
288+
label := doIncrement;
289+
other := nuthing
290+
}
291+
| Elapsed@{timers := ts} := nothing;

tests/positive/Isabelle/isabelle/Program.thy

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,4 +316,41 @@ record RR =
316316
fun x :: "RR \<Rightarrow> Name" where
317317
"x (| RR.x = x' |) = x'"
318318

319+
(* Type constructor identifiers *)
320+
record ('A, 'L, 'X) GuardOutput =
321+
args :: "'A list"
322+
label :: 'L
323+
other :: 'X
324+
325+
fun args :: "('A, 'L, 'X) GuardOutput \<Rightarrow> 'A list" where
326+
"args (| GuardOutput.args = args', GuardOutput.label = label', GuardOutput.other = other' |) =
327+
args'"
328+
329+
fun label :: "('A, 'L, 'X) GuardOutput \<Rightarrow> 'L" where
330+
"label (| GuardOutput.args = args', GuardOutput.label = label', GuardOutput.other = other' |) =
331+
label'"
332+
333+
fun other :: "('A, 'L, 'X) GuardOutput \<Rightarrow> 'X" where
334+
"other (| GuardOutput.args = args', GuardOutput.label = label', GuardOutput.other = other' |) =
335+
other'"
336+
337+
datatype GuardReturnLabel
338+
= doIncrement |
339+
doRespond nat
340+
341+
datatype GuardReturnOther
342+
= nuthing
343+
344+
datatype GuardReturnArgs
345+
= ReplyTo nat
346+
347+
fun ifIncrement :: "(nat, nat) Trigger \<Rightarrow> ((GuardReturnArgs, GuardReturnLabel, GuardReturnOther) GuardOutput) option" where
348+
"ifIncrement (MessageArrived m) =
349+
(Some (let
350+
args' = [];
351+
label' = doIncrement;
352+
other' = nuthing
353+
in (| GuardOutput.args = args', GuardOutput.label = label', GuardOutput.other = other' |)))" |
354+
"ifIncrement (Elapsed ts) = None"
355+
319356
end

0 commit comments

Comments
 (0)