Skip to content

Commit

Permalink
fix implicit record arguments and let-bindings for lets
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszcz committed Nov 29, 2024
1 parent 5e897df commit 7d7e875
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 33 deletions.
18 changes: 14 additions & 4 deletions src/Juvix/Compiler/Backend/Isabelle/Translation/FromTyped.hs
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,11 @@ goModule onlyTypes infoTable Internal.Module {..} =

goRecordFields :: [Internal.FunctionParameter] -> [a] -> [(Name, a)]
goRecordFields argtys args = case (argtys, args) of
(ty : argtys', arg' : args') -> (fromMaybe (defaultName (getLoc ty) "_") (ty ^. Internal.paramName), arg') : goRecordFields argtys' args'
(param : argtys', arg' : args')
| param ^. Internal.paramImplicit == Internal.Explicit ->
(fromMaybe (defaultName (getLoc param) "_") (param ^. Internal.paramName), arg') : goRecordFields argtys' args'
| otherwise ->
goRecordFields argtys' args'
_ -> []

goExpression' :: Internal.Expression -> Expression
Expand Down Expand Up @@ -560,6 +564,8 @@ goModule onlyTypes infoTable Internal.Module {..} =
fn' <- goExpression fn
args' <- mapM goExpression args
return $ mkApp fn' args'
| _appImplicit /= Internal.Explicit =
goExpression _appLeft
| otherwise = do
l <- goExpression _appLeft
r <- goExpression _appRight
Expand Down Expand Up @@ -722,7 +728,7 @@ goModule onlyTypes infoTable Internal.Module {..} =
_ -> Nothing
_ -> Nothing
where
(fn, args) = Internal.unfoldApplication app
(fn, args) = Internal.unfoldExplicitApplication app

getRecordUpdate :: Internal.Application -> Maybe (Name, [Name], Internal.Expression, [(Name, Internal.Expression)])
getRecordUpdate Internal.Application {..} = case _appLeft of
Expand All @@ -745,7 +751,7 @@ goModule onlyTypes infoTable Internal.Module {..} =
_ -> Nothing
_ -> Nothing
where
(fn, args) = Internal.unfoldApplication app
(fn, args) = Internal.unfoldExplicitApplication app
_ -> Nothing
_ -> Nothing
_ -> Nothing
Expand Down Expand Up @@ -792,7 +798,11 @@ goModule onlyTypes infoTable Internal.Module {..} =

goLet :: Internal.Let -> Sem r Expression
goLet Internal.Let {..} = do
let fdefs = concatMap toFunDefs (toList _letClauses)
let fdefs =
filter (not . Internal.isTypeConstructor . (^. Internal.funDefType))
. concatMap toFunDefs
. toList
$ _letClauses
cls <- mapM goFunDef fdefs
let ns = zipExact (map (^. Internal.funDefName) fdefs) (map (^. letClauseName) cls)
expr <- localNames ns $ goExpression _letExpression
Expand Down
9 changes: 9 additions & 0 deletions src/Juvix/Compiler/Internal/Extra/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,15 @@ unfoldExpressionApp = swap . run . runAccumListReverse . go
unfoldApplication :: Application -> (Expression, NonEmpty Expression)
unfoldApplication = fmap (fmap (^. appArg)) . unfoldApplication'

unfoldExplicitApplication :: Application -> (Expression, [Expression])
unfoldExplicitApplication =
fmap
( fmap (^. appArg)
. filter (\x -> x ^. appArgIsImplicit == Explicit)
. toList
)
. unfoldApplication'

-- | A fold over all transitive children, including self
patternCosmos :: SimpleFold Pattern Pattern
patternCosmos f p = case p of
Expand Down
79 changes: 50 additions & 29 deletions tests/positive/Isabelle/Program.juvix
Original file line number Diff line number Diff line change
Expand Up @@ -196,44 +196,39 @@ nf (n1 n2 : Int) : Bool := n1 - n2 >= n1 || n2 <= n1 + n2;

-- Nested record patterns

type MessagePacket (MessageType : Type) : Type := mkMessagePacket {
target : Nat;
mailbox : Maybe Nat;
message : MessageType;
};
type MessagePacket (MessageType : Type) : Type :=
mkMessagePacket {
target : Nat;
mailbox : Maybe Nat;
message : MessageType
};

type EnvelopedMessage (MessageType : Type) : Type :=
mkEnvelopedMessage {
sender : Maybe Nat;
packet : MessagePacket MessageType;
packet : MessagePacket MessageType
};

type Timer (HandleType : Type): Type := mkTimer {
time : Nat;
handle : HandleType;
};
type Timer (HandleType : Type) : Type :=
mkTimer {
time : Nat;
handle : HandleType
};

type Trigger (MessageType : Type) (HandleType : Type) :=
| MessageArrived { envelope : EnvelopedMessage MessageType; }
| Elapsed { timers : List (Timer HandleType) };
| MessageArrived {envelope : EnvelopedMessage MessageType}
| Elapsed {timers : List (Timer HandleType)};

getMessageFromTrigger : {M H : Type} -> Trigger M H -> Maybe M
| (MessageArrived@{
envelope := (mkEnvelopedMessage@{
packet := (mkMessagePacket@{
message := m })})})
:= just m
| _ := nothing;

| MessageArrived@{envelope := mkEnvelopedMessage@{packet := mkMessagePacket@{message := m}}} :=
just m
| _ := nothing;

getMessageFromTrigger' {M H} (t : Trigger M H) : Maybe M :=
case t of
| (MessageArrived@{
envelope := (mkEnvelopedMessage@{
packet := (mkMessagePacket@{
message := m })})})
:= just m
| _ := nothing;
case t of
| MessageArrived@{envelope := mkEnvelopedMessage@{packet := mkMessagePacket@{message := m}}} :=
just m
| _ := nothing;

-- Syntax aliases

Expand All @@ -245,6 +240,32 @@ idT (x : T) : T := x;

t : T := 0;

type RR := mkRR {
x : T
};
type RR := mkRR {x : T};

-- Type constructor identifiers

type GuardOutput (A L X : Type) :=
mkGuardOutput {
args : List A;
label : L;
other : X
};

type GuardReturnLabel :=
| doIncrement
| doRespond Nat;

type GuardReturnOther := nuthing;

type GuardReturnArgs := ReplyTo Nat;

ifIncrement
: Trigger Nat Nat -> Maybe (GuardOutput GuardReturnArgs GuardReturnLabel GuardReturnOther)
| MessageArrived@{envelope := m} :=
just
mkGuardOutput@{
args := [];
label := doIncrement;
other := nuthing
}
| Elapsed@{timers := ts} := nothing;
37 changes: 37 additions & 0 deletions tests/positive/Isabelle/isabelle/Program.thy
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,44 @@ definition t :: Name where
record RR =
x :: nat

(* Type constructor identifiers *)
record ('A, 'L, 'X) GuardOutput =
args :: "'A list"
label :: 'L
other :: 'X

datatype GuardReturnLabel
= doIncrement |
doRespond nat

datatype GuardReturnOther
= nuthing

datatype GuardReturnArgs
= ReplyTo nat

fun x :: "RR \<Rightarrow> Name" where
"x (| RR.x = x' |) = x'"

fun args :: "('A, 'L, 'X) GuardOutput \<Rightarrow> 'A list" where
"args (| GuardOutput.args = args', GuardOutput.label = label', GuardOutput.other = other' |) =
args'"

fun label :: "('A, 'L, 'X) GuardOutput \<Rightarrow> 'L" where
"label (| GuardOutput.args = args', GuardOutput.label = label', GuardOutput.other = other' |) =
label'"

fun other :: "('A, 'L, 'X) GuardOutput \<Rightarrow> 'X" where
"other (| GuardOutput.args = args', GuardOutput.label = label', GuardOutput.other = other' |) =
other'"

fun ifIncrement :: "(nat, nat) Trigger \<Rightarrow> ((GuardReturnArgs, GuardReturnLabel, GuardReturnOther) GuardOutput) option" where
"ifIncrement (MessageArrived m) =
(Some (let
args' = [];
label' = doIncrement;
other' = nuthing
in (| GuardOutput.args = args', GuardOutput.label = label', GuardOutput.other = other' |)))" |
"ifIncrement (Elapsed ts) = None"

end

0 comments on commit 7d7e875

Please sign in to comment.