From Velus Require Import Common.
From Velus Require Import Operators.
From Velus Require Import CoreExpr.CESyntax.
From Velus Require Import Clocks.
From Velus Require Import NLustre.NLSyntax.
From Coq Require Import List.
Import List.ListNotations.
Open Scope list_scope.
Module Type NLNORMALARGS
(
Import Ids :
IDS)
(
Import Op :
OPERATORS)
(
Import CESyn :
CESYNTAX Op)
(
Import Syn :
NLSYNTAX Ids Op CESyn).
The normal_args predicate defines a normalization condition on
node arguments -- those that are not on the base clock can only
be instantiated with constants or variables -- that is necessary
for correct generation of Obc/Clight.
To see why this is necessary. Consider the NLustre equation: y =
f(1, 3 when ck / x)
with x on the clock ck, and y on the base clock. The generated
Obc code is y := f(1, 3 / x)
which has no semantics when ck = false, since x = None then 3 /
x is not given a meaning.
Consider what would happen were the semantics of 3 / x =
None. There are two possible problems.
If x is a local variable, then x = None in Obc implies that x =
VUndef in Clight and 3 / VUndef has no semantics. I.e., the Obc
program having a semantics would not be enough to guarantee that
the Clight program generated from it does.
If x is a state variable, then x = None in Obc implies that x
could be anything in Clight (though it would be defined since
state variables are stored in a global structure). We might then
prove that x is never 0 (when ck = true) in the original Lustre
program. This would guarantee the absence of division by zero in
the generated Obc (since x is None when ck = false), but not in
the generated Clight code; since None in Obc means "don't care"
in Clight, x may well contain the value 0 when ck is false (for
instance, if ck = false at the first reaction).
Inductive normal_args_eq (
G:
global) :
equation ->
Prop :=
|
CEqDef:
forall x ck ce,
normal_args_eq G (
EqDef x ck ce)
|
CEqApp:
forall xs ck f les r n,
find_node f G =
Some n ->
Forall2 noops_exp (
map (
fun '(
_, (
_,
ck)) =>
ck)
n.(
n_in))
les ->
normal_args_eq G (
EqApp xs ck f les r)
|
CEqFby:
forall x ck v0 le,
normal_args_eq G (
EqFby x ck v0 le).
Definition normal_args_node (
G:
global) (
n:
node) :
Prop :=
Forall (
normal_args_eq G)
n.(
n_eqs).
Fixpoint normal_args (
G:
list node) :
Prop :=
match G with
| [] =>
True
|
n ::
G' =>
normal_args_node G n /\
normal_args G'
end.
End NLNORMALARGS.
Module NLNormalArgsFun
(
Ids :
IDS)
(
Op :
OPERATORS)
(
CESyn :
CESYNTAX Op)
(
Syn :
NLSYNTAX Ids Op CESyn)
<:
NLNORMALARGS Ids Op CESyn Syn.
Include NLNORMALARGS Ids Op CESyn Syn.
End NLNormalArgsFun.