refactor(clerk): add ninja support for remaining catala backends

TODO:
	 * Refactoring
	 * Manage scope + output backends
This commit is contained in:
Emile Rolley 2022-02-15 20:32:17 +01:00
parent ccd90bcbf6
commit a9f949ffc9
20 changed files with 1081 additions and 18 deletions

12
build_system/Makefile Normal file
View File

@ -0,0 +1,12 @@
CATALA_BIN=../_build/default/compiler/catala.exe
CLERK_BIN=../_build/default/build_system/clerk.exe
CLERK=$(CLERK_BIN) --exe $(CATALA_BIN)
simple_test:
@$(CLERK) test tests
reset:
@$(CLERK) test tests -r
test: simple_test reset

View File

@ -106,7 +106,7 @@ let catala_backend_to_string (backend : Cli.backend_option) : string =
match backend with
| Cli.Interpret -> "Interpret"
| Cli.Makefile -> "Makefile"
| Cli.OCaml -> "Ocaml"
| Cli.OCaml -> "OCaml"
| Cli.Scopelang -> "Scopelang"
| Cli.Dcalc -> "Dcalc"
| Cli.Latex -> "Latex"
@ -219,7 +219,7 @@ type testing_result = { error_code : int; number_of_tests_run : int; number_corr
(* ]) *)
(* in *)
(** [add_reset_rules catala_exe_opts rules] adds ninja rules used to reset test files in to [rules]
(** [add_reset_rules catala_exe_opts rules] adds ninja rules used to reset test files into [rules]
and returns it.*)
let add_reset_rules (catala_exe_opts : string) (rules : Rule.t Nj.RuleMap.t) : Rule.t Nj.RuleMap.t =
let reset_common_cmd_exprs =
@ -271,7 +271,7 @@ let add_reset_rules (catala_exe_opts : string) (rules : Rule.t Nj.RuleMap.t) : R
|> add reset_with_scope_rule.name reset_with_scope_rule
|> add reset_without_scope_rule.name reset_without_scope_rule)
(** [add_test_rules catala_exe_opts rules] adds ninja rules used to test files in to [rules] and
(** [add_test_rules catala_exe_opts rules] adds ninja rules used to test files into [rules] and
returns it.*)
let add_test_rules (catala_exe_opts : string) (rules : Rule.t Nj.RuleMap.t) : Rule.t Nj.RuleMap.t =
let test_common_cmd_exprs =
@ -281,7 +281,6 @@ let add_test_rules (catala_exe_opts : string) (rules : Rule.t Nj.RuleMap.t) : Ru
Var "tested_file";
Var "extra_flags";
Lit "--unstyled";
Var "reset_test_output";
Lit "2>&1 | colordiff -u -b";
Var "expected_output";
Lit "-";
@ -314,23 +313,136 @@ let add_test_rules (catala_exe_opts : string) (rules : Rule.t Nj.RuleMap.t) : Ru
Lit "TEST on file"; Var "tested_file"; Lit "with the"; Var "catala_cmd"; Lit "command";
])
in
let run_and_display_final_message =
Nj.Rule.make "run_and_display_final_message"
~command:Nj.Expr.(Seq [ Lit ":" ])
~description:Nj.Expr.(Seq [ Lit "All tests"; Var "test_file_or_folder"; Lit "passed!" ])
in
Nj.RuleMap.(
rules
|> add test_with_scope_rule.name test_with_scope_rule
|> add test_without_scope_rule.name test_without_scope_rule
|> add run_and_display_final_message.name run_and_display_final_message)
|> add test_without_scope_rule.name test_without_scope_rule)
(** [add_reset_with_ouput_rules catala_exe_opts rules] adds ninja rules used to reset test files
using an output flag into [rules] and returns it.
TODO: to factorize with add_reset_rules, only Lit '-o' is changing. *)
let add_reset_with_output_rules (catala_exe_opts : string) (rules : Rule.t Nj.RuleMap.t) :
Rule.t Nj.RuleMap.t =
let reset_common_cmd_exprs =
Nj.Expr.
[
Var "catala_cmd";
Var "tested_file";
Var "extra_flags";
Lit "--unstyled";
Lit "-o";
Var "expected_output";
Lit "2>&1";
]
in
let reset_with_scope_and_output_rule =
Nj.Rule.make "reset_with_scope_and_output"
~command:
Nj.Expr.(Seq ([ Lit catala_exe_opts; Lit "-s"; Var "scope" ] @ reset_common_cmd_exprs))
~description:
Nj.Expr.(
Seq
[
Lit "RESET scope";
Var "scope";
Lit "of file";
Var "tested_file";
Lit "with the";
Var "catala_cmd";
Lit "command";
])
in
let reset_without_scope_and_output_rule =
Nj.Rule.make "reset_without_scope_and_output"
~command:Nj.Expr.(Seq (Lit catala_exe_opts :: reset_common_cmd_exprs))
~description:
Nj.Expr.(
Seq
[
Lit "RESET";
Lit "file";
Var "tested_file";
Lit "with the";
Var "catala_cmd";
Lit "command";
])
in
Nj.RuleMap.(
rules
|> add reset_with_scope_and_output_rule.name reset_with_scope_and_output_rule
|> add reset_without_scope_and_output_rule.name reset_without_scope_and_output_rule)
(** [add_test_with_output_rules catala_exe_opts rules] adds ninja rules used to test files using an
output flag into [rules] and returns it.*)
let add_test_with_output_rules (catala_exe_opts : string) (rules : Rule.t Nj.RuleMap.t) :
Rule.t Nj.RuleMap.t =
(* catala Ocaml build_system/tests/test_array/good/aggregation_2.catala_en --unstyled -o
/tmp/clerk_7a8ebd_Ocaml ; colordiff -u -b
build_system/tests/test_array/good/output/aggregation_2.catala_en.ml /tmp/clerk_7a8ebd_Ocaml*)
let test_common_cmd_exprs =
Nj.Expr.
[
Var "catala_cmd";
Var "tested_file";
Var "extra_flags";
Lit "--unstyled";
Lit "-o";
Var "tmp_file";
Lit "; colordiff -u -b";
Var "expected_output";
Var "tmp_file";
]
in
Cli.debug_print (Printf.sprintf "==== catala_exe_opts = %s ========" catala_exe_opts);
let test_with_scope_and_output_rule =
Nj.Rule.make "test_with_scope_and_output"
~command:
Nj.Expr.(Seq ([ Lit catala_exe_opts; Lit "-s"; Var "scope" ] @ test_common_cmd_exprs))
~description:
Nj.Expr.(
Seq
[
Lit "TEST scope";
Var "scope";
Lit "of file";
Var "tested_file";
Lit "with the";
Var "catala_cmd";
Lit "command";
])
in
let test_without_scope_and_output_rule =
Nj.Rule.make "test_without_scope_and_output"
~command:Nj.Expr.(Seq (Lit catala_exe_opts :: test_common_cmd_exprs))
~description:
Nj.Expr.(
Seq
[
Lit "TEST on file"; Var "tested_file"; Lit "with the"; Var "catala_cmd"; Lit "command";
])
in
Nj.RuleMap.(
rules
|> add test_with_scope_and_output_rule.name test_with_scope_and_output_rule
|> add test_without_scope_and_output_rule.name test_without_scope_and_output_rule)
(** [ninja_start catala_exe] returns the inital [ninja] data structure with rules needed to reset
and test files. *)
let ninja_start (catala_exe : string) (catala_opts : string) : ninja =
let catala_exe_opts = catala_exe ^ " " ^ catala_opts in
let run_and_display_final_message =
Nj.Rule.make "run_and_display_final_message"
~command:Nj.Expr.(Seq [ Lit ":" ])
~description:Nj.Expr.(Seq [ Lit "All tests"; Var "test_file_or_folder"; Lit "passed!" ])
in
{
rules = Nj.RuleMap.(empty |> add_reset_rules catala_exe_opts |> add_test_rules catala_exe_opts);
rules =
Nj.RuleMap.(
empty |> add_reset_rules catala_exe_opts |> add_test_rules catala_exe_opts
|> add_test_with_output_rules catala_exe_opts
|> add_reset_with_output_rules catala_exe_opts
|> add run_and_display_final_message.name run_and_display_final_message);
builds = Nj.BuildMap.empty;
}
@ -390,12 +502,43 @@ let collect_all_ninja_build (ninja : ninja) (tested_file : string) (reset_test_o
ninja.builds;
},
test_names ^ " $\n " ^ test_name )
| backend ->
catala_backend_to_string backend
|> Printf.sprintf "%s: Catala backend '%s' is not yet supported. "
expected_output.complete_filename
|> Cli.warning_print;
(ninja, test_names))
| Cli.Python | Cli.OCaml | Cli.Latex | Cli.Html | Cli.Makefile ->
let tmp_file =
Filename.temp_file "clerk_" ("_" ^ catala_backend_to_string expected_output.backend)
in
let vars =
[
("catala_cmd", Nj.Expr.Lit (catala_backend_to_string expected_output.backend));
("tested_file", Nj.Expr.Lit tested_file);
( "expected_output",
Nj.Expr.Lit (expected_output.output_dir ^ expected_output.complete_filename) );
("tmp_file", Nj.Expr.Lit tmp_file);
]
in
let output_build_kind = if reset_test_outputs then "reset" else "test" in
let test_name, rule, vars =
match expected_output.scope with
| Some scope ->
( Printf.sprintf "%s_%s_%s" output_build_kind scope tested_file
|> Nj.Build.unpath,
output_build_kind ^ "_with_scope_and_output",
("scope", Nj.Expr.Lit scope) :: vars )
| None ->
( Printf.sprintf "%s_%s_%s" output_build_kind
(catala_backend_to_string expected_output.backend)
tested_file
|> Nj.Build.unpath,
output_build_kind ^ "_without_scope_and_output",
vars )
in
( {
ninja with
builds =
Nj.BuildMap.add test_name
(Nj.Build.make_with_vars ~outputs:[ Nj.Expr.Lit test_name ] ~rule ~vars)
ninja.builds;
},
test_names ^ " $\n " ^ test_name ))
(ninja, "") expected_outputs
in
let test_name =

View File

@ -0,0 +1,22 @@
## Article
```catala
declaration scope A:
output x content collection money
scope A:
definition x equals [$0; $4 +$ $5; $8 *$ 0.65]
declaration scope B:
a scope A
output max content money
output min content money
output y content money
output z content integer
scope B:
definition max equals maximum money initial $0 for m in a.x of m *$ 2.0
definition min equals minimum money initial $20 for m in a.x of m +$ $5
definition y equals sum money for m in a.x of (m +$ $1)
definition z equals number for m in a.x of (m >=$ $8.95)
```

View File

@ -0,0 +1,26 @@
## Article
```catala
declaration structure S:
data id content integer
data income content money
declaration scope A:
context output x content collection S
scope A:
definition x equals [
S { -- id: 0 -- income: $0 };
S { -- id: 1 -- income: $4 +$ $5 };
S { -- id: 2 -- income: $8 *$ 0.65 }
]
declaration scope B:
a scope A
output argmax content S
output argmin content S
scope B:
definition argmax equals content maximum money initial S { -- id: -1 --income: $0 } for m in a.x of (m.income *$ 2.0)
definition argmin equals content minimum money initial S { -- id: -1 --income: $20 } for m in a.x of (m.income +$ $5)
```

View File

@ -0,0 +1,177 @@
(** This file has been generated by the Catala compiler, do not edit! *)
open Runtime
[@@@ocaml.warning "-4-26-27-32-41-42"]
type s = { id : integer; income : money }
type a_out = { x_out : s array }
type a_in = { x_in : unit -> s array }
type b_out = { argmax_out : s; argmin_out : s }
type b_in = unit
let a (a_in : a_in) =
let x_ : unit -> s array = a_in.x_in in
let x_ : s array =
try
handle_default
[| (fun (_ : _) -> x_ ()) |]
(fun (_ : _) -> true)
(fun (_ : _) ->
handle_default
[|
(fun (_ : _) ->
handle_default [||]
(fun (_ : _) -> true)
(fun (_ : _) ->
handle_default
[|
(fun (_ : _) ->
handle_default [||]
(fun (_ : _) -> true)
(fun (_ : _) ->
[|
{ id = integer_of_string "0"; income = money_of_cents_string "0" };
{
id = integer_of_string "1";
income =
money_of_cents_string "400" +$ money_of_cents_string "500";
};
{
id = integer_of_string "2";
income = money_of_cents_string "800" *$ decimal_of_string "0.65";
};
|]));
|]
(fun (_ : _) -> false)
(fun (_ : _) -> raise EmptyError)));
|]
(fun (_ : _) -> true)
(fun (_ : _) ->
handle_default
[|
(fun (_ : _) ->
handle_default [||] (fun (_ : _) -> false) (fun (_ : _) -> raise EmptyError));
|]
(fun (_ : _) -> false)
(fun (_ : _) -> raise EmptyError)))
with EmptyError ->
raise
(NoValueProvided
{
filename = "tests/test_array/good/aggregation_2.catala_en";
start_line = 9;
start_column = 19;
end_line = 9;
end_column = 20;
law_headings = [ "Article" ];
})
in
{ x_out = x_ }
let b (b_in : b_in) =
let a_dot_x_ : unit -> s array = fun (_ : unit) -> raise EmptyError in
let result_ : a_out = a { x_in = a_dot_x_ } in
let a_dot_x_ : s array = result_.x_out in
let argmin_ : s =
try
handle_default
[|
(fun (_ : _) ->
handle_default [||]
(fun (_ : _) -> true)
(fun (_ : _) ->
handle_default
[|
(fun (_ : _) ->
handle_default [||]
(fun (_ : _) -> true)
(fun (_ : _) ->
let predicate_ : _ =
fun (m_ : _) -> m_.income +$ money_of_cents_string "500"
in
Array.fold_left
(fun (acc_ : _) (item_ : _) ->
if predicate_ acc_ <$ predicate_ item_ then acc_ else item_)
{
id = ~-!(integer_of_string "1");
income = money_of_cents_string "2000";
}
a_dot_x_));
|]
(fun (_ : _) -> false)
(fun (_ : _) -> raise EmptyError)));
|]
(fun (_ : _) -> true)
(fun (_ : _) ->
handle_default
[|
(fun (_ : _) ->
handle_default [||] (fun (_ : _) -> false) (fun (_ : _) -> raise EmptyError));
|]
(fun (_ : _) -> false)
(fun (_ : _) -> raise EmptyError))
with EmptyError ->
raise
(NoValueProvided
{
filename = "tests/test_array/good/aggregation_2.catala_en";
start_line = 21;
start_column = 11;
end_line = 21;
end_column = 17;
law_headings = [ "Article" ];
})
in
let argmax_ : s =
try
handle_default
[|
(fun (_ : _) ->
handle_default [||]
(fun (_ : _) -> true)
(fun (_ : _) ->
handle_default
[|
(fun (_ : _) ->
handle_default [||]
(fun (_ : _) -> true)
(fun (_ : _) ->
let predicate_ : _ =
fun (m_ : _) -> m_.income *$ decimal_of_string "2."
in
Array.fold_left
(fun (acc_ : _) (item_ : _) ->
if predicate_ acc_ >$ predicate_ item_ then acc_ else item_)
{ id = ~-!(integer_of_string "1"); income = money_of_cents_string "0" }
a_dot_x_));
|]
(fun (_ : _) -> false)
(fun (_ : _) -> raise EmptyError)));
|]
(fun (_ : _) -> true)
(fun (_ : _) ->
handle_default
[|
(fun (_ : _) ->
handle_default [||] (fun (_ : _) -> false) (fun (_ : _) -> raise EmptyError));
|]
(fun (_ : _) -> false)
(fun (_ : _) -> raise EmptyError))
with EmptyError ->
raise
(NoValueProvided
{
filename = "tests/test_array/good/aggregation_2.catala_en";
start_line = 20;
start_column = 11;
end_line = 20;
end_column = 17;
law_headings = [ "Article" ];
})
in
{ argmax_out = argmax_; argmin_out = argmin_ }

View File

@ -0,0 +1,11 @@
## Unit testing for collection concatenation.
```catala
declaration scope A:
output x content collection integer
output y content collection integer
scope A:
definition x equals [0; 1; 2] ++ [3; 4; 5; 6]
definition y equals x ++ ([7; 8; 9] ++ [10])
```

View File

@ -0,0 +1,18 @@
## Article
```catala
declaration scope A:
output x content collection money
scope A:
definition x equals [$0; $4 +$ $5; $8 *$ 0.65]
declaration scope B:
a scope A
output y content collection money
output z content collection boolean
scope B:
definition y equals filter for m in a.x of (m >=$ $4.95)
definition z equals map for m in a.x of (m >=$ $4.95)
```

View File

@ -0,0 +1,2 @@
[RESULT] Computation successful! Results:
[RESULT] x = [$0.00; $9.00; $5.20]

View File

@ -0,0 +1,5 @@
[RESULT] Computation successful! Results:
[RESULT] max = $18.00
[RESULT] min = $5.00
[RESULT] y = $17.20
[RESULT] z = 1

View File

@ -0,0 +1,4 @@
[RESULT] Computation successful! Results:
[RESULT] x =
[S {"id"= 0; "income"= $0.00}; S {"id"= 1; "income"= $9.00};
S {"id"= 2; "income"= $5.20}]

View File

@ -0,0 +1,177 @@
(** This file has been generated by the Catala compiler, do not edit! *)
open Runtime
[@@@ocaml.warning "-4-26-27-32-41-42"]
type s = { id : integer; income : money }
type a_out = { x_out : s array }
type a_in = { x_in : unit -> s array }
type b_out = { argmax_out : s; argmin_out : s }
type b_in = unit
let a (a_in : a_in) =
let x_ : unit -> s array = a_in.x_in in
let x_ : s array =
try
handle_default
[| (fun (_ : _) -> x_ ()) |]
(fun (_ : _) -> true)
(fun (_ : _) ->
handle_default
[|
(fun (_ : _) ->
handle_default [||]
(fun (_ : _) -> true)
(fun (_ : _) ->
handle_default
[|
(fun (_ : _) ->
handle_default [||]
(fun (_ : _) -> true)
(fun (_ : _) ->
[|
{ id = integer_of_string "0"; income = money_of_cents_string "0" };
{
id = integer_of_string "1";
income =
money_of_cents_string "400" +$ money_of_cents_string "500";
};
{
id = integer_of_string "2";
income = money_of_cents_string "800" *$ decimal_of_string "0.65";
};
|]));
|]
(fun (_ : _) -> false)
(fun (_ : _) -> raise EmptyError)));
|]
(fun (_ : _) -> true)
(fun (_ : _) ->
handle_default
[|
(fun (_ : _) ->
handle_default [||] (fun (_ : _) -> false) (fun (_ : _) -> raise EmptyError));
|]
(fun (_ : _) -> false)
(fun (_ : _) -> raise EmptyError)))
with EmptyError ->
raise
(NoValueProvided
{
filename = "build_system/tests/test_array/good/aggregation_2.catala_en";
start_line = 9;
start_column = 19;
end_line = 9;
end_column = 20;
law_headings = [ "Article" ];
})
in
{ x_out = x_ }
let b (b_in : b_in) =
let a_dot_x_ : unit -> s array = fun (_ : unit) -> raise EmptyError in
let result_ : a_out = a { x_in = a_dot_x_ } in
let a_dot_x_ : s array = result_.x_out in
let argmin_ : s =
try
handle_default
[|
(fun (_ : _) ->
handle_default [||]
(fun (_ : _) -> true)
(fun (_ : _) ->
handle_default
[|
(fun (_ : _) ->
handle_default [||]
(fun (_ : _) -> true)
(fun (_ : _) ->
let predicate_ : _ =
fun (m_ : _) -> m_.income +$ money_of_cents_string "500"
in
Array.fold_left
(fun (acc_ : _) (item_ : _) ->
if predicate_ acc_ <$ predicate_ item_ then acc_ else item_)
{
id = ~-!(integer_of_string "1");
income = money_of_cents_string "2000";
}
a_dot_x_));
|]
(fun (_ : _) -> false)
(fun (_ : _) -> raise EmptyError)));
|]
(fun (_ : _) -> true)
(fun (_ : _) ->
handle_default
[|
(fun (_ : _) ->
handle_default [||] (fun (_ : _) -> false) (fun (_ : _) -> raise EmptyError));
|]
(fun (_ : _) -> false)
(fun (_ : _) -> raise EmptyError))
with EmptyError ->
raise
(NoValueProvided
{
filename = "build_system/tests/test_array/good/aggregation_2.catala_en";
start_line = 21;
start_column = 11;
end_line = 21;
end_column = 17;
law_headings = [ "Article" ];
})
in
let argmax_ : s =
try
handle_default
[|
(fun (_ : _) ->
handle_default [||]
(fun (_ : _) -> true)
(fun (_ : _) ->
handle_default
[|
(fun (_ : _) ->
handle_default [||]
(fun (_ : _) -> true)
(fun (_ : _) ->
let predicate_ : _ =
fun (m_ : _) -> m_.income *$ decimal_of_string "2."
in
Array.fold_left
(fun (acc_ : _) (item_ : _) ->
if predicate_ acc_ >$ predicate_ item_ then acc_ else item_)
{ id = ~-!(integer_of_string "1"); income = money_of_cents_string "0" }
a_dot_x_));
|]
(fun (_ : _) -> false)
(fun (_ : _) -> raise EmptyError)));
|]
(fun (_ : _) -> true)
(fun (_ : _) ->
handle_default
[|
(fun (_ : _) ->
handle_default [||] (fun (_ : _) -> false) (fun (_ : _) -> raise EmptyError));
|]
(fun (_ : _) -> false)
(fun (_ : _) -> raise EmptyError))
with EmptyError ->
raise
(NoValueProvided
{
filename = "build_system/tests/test_array/good/aggregation_2.catala_en";
start_line = 20;
start_column = 11;
end_line = 20;
end_column = 17;
law_headings = [ "Article" ];
})
in
{ argmax_out = argmax_; argmin_out = argmin_ }

View File

@ -0,0 +1,3 @@
[RESULT] Computation successful! Results:
[RESULT] argmax = S {"id"= 1; "income"= $9.00}
[RESULT] argmin = S {"id"= 0; "income"= $0.00}

View File

@ -0,0 +1,168 @@
(** This file has been generated by the Catala compiler, do not edit! *)
open Runtime
[@@@ocaml.warning "-4-26-27-32-41-42"]
type s = {
id: integer;
income: money;
}
type a_out = {
x_out: s array;
}
type a_in = {
x_in: unit -> (s array);
}
type b_out = {
argmax_out: s;
argmin_out: s;
}
type b_in = unit
let a =
fun (a_in: a_in) -> let x_ : unit -> (s array) = (a_in.x_in)
in
let x_ : s array =
((try
(handle_default ([|(fun (_: _) -> x_ ())|]) (fun (_: _) -> true)
(fun (_: _) ->
handle_default
([|(fun (_: _) ->
handle_default ([||]) (fun (_: _) -> true)
(fun (_: _) ->
handle_default
([|(fun (_: _) ->
handle_default ([||])
(fun (_: _) -> true)
(fun (_: _) ->
[|{id = (integer_of_string "0");
income =
(money_of_cents_string "0")};
{id = (integer_of_string "1");
income =
((money_of_cents_string
"400") +$
(money_of_cents_string
"500"))};
{id = (integer_of_string "2");
income =
((money_of_cents_string
"800") *$
(decimal_of_string "0.65"))}|]))|])
(fun (_: _) -> false)
(fun (_: _) -> raise EmptyError)))|])
(fun (_: _) -> true)
(fun (_: _) ->
handle_default
([|(fun (_: _) ->
handle_default ([||]) (fun (_: _) -> false)
(fun (_: _) -> raise EmptyError))|])
(fun (_: _) -> false) (fun (_: _) -> raise EmptyError))))
with EmptyError -> (raise (NoValueProvided
{filename = "tests/test_array/good/aggregation_2.catala_en";
start_line=9; start_column=19; end_line=9; end_column=20;
law_headings=["Article"]})))) in
{x_out = x_}
let b =
fun (b_in: b_in) ->
let a_dot_x_ : unit -> (s array) = (fun (_: unit) -> (raise EmptyError))
in
let result_ : a_out = (((a) {x_in = a_dot_x_}))
in
let a_dot_x_ : s array = (result_.x_out)
in
let argmin_ : s =
((try
(handle_default
([|(fun (_: _) ->
handle_default ([||]) (fun (_: _) -> true)
(fun (_: _) ->
handle_default
([|(fun (_: _) ->
handle_default ([||]) (fun (_: _) -> true)
(fun (_: _) ->
let predicate_ : _ =
(fun (m_: _) ->
(m_.income) +$
(money_of_cents_string "500"))
in
(Array.fold_left
(fun (acc_: _) (item_: _) ->
if
((predicate_ acc_) <$
(predicate_ item_)) then
acc_ else item_)
{id = (~-! (integer_of_string "1"));
income = (money_of_cents_string
"2000")} a_dot_x_)))|])
(fun (_: _) -> false)
(fun (_: _) -> raise EmptyError)))|])
(fun (_: _) -> true)
(fun (_: _) ->
handle_default
([|(fun (_: _) ->
handle_default ([||]) (fun (_: _) -> false)
(fun (_: _) -> raise EmptyError))|])
(fun (_: _) -> false) (fun (_: _) -> raise EmptyError)))
with EmptyError -> (raise (NoValueProvided
{filename = "tests/test_array/good/aggregation_2.catala_en";
start_line=21; start_column=11; end_line=21; end_column=17;
law_headings=["Article"]}))))
in
let argmax_ : s =
((try
(handle_default
([|(fun (_: _) ->
handle_default ([||]) (fun (_: _) -> true)
(fun (_: _) ->
handle_default
([|(fun (_: _) ->
handle_default ([||]) (fun (_: _) -> true)
(fun (_: _) ->
let predicate_ : _ =
(fun (m_: _) ->
(m_.income) *$
(decimal_of_string "2."))
in
(Array.fold_left
(fun (acc_: _) (item_: _) ->
if
((predicate_ acc_) >$
(predicate_ item_)) then
acc_ else item_)
{id = (~-! (integer_of_string "1"));
income = (money_of_cents_string
"0")} a_dot_x_)))|])
(fun (_: _) -> false)
(fun (_: _) -> raise EmptyError)))|])
(fun (_: _) -> true)
(fun (_: _) ->
handle_default
([|(fun (_: _) ->
handle_default ([||]) (fun (_: _) -> false)
(fun (_: _) -> raise EmptyError))|])
(fun (_: _) -> false) (fun (_: _) -> raise EmptyError)))
with EmptyError -> (raise (NoValueProvided
{filename = "tests/test_array/good/aggregation_2.catala_en";
start_line=20; start_column=11; end_line=20; end_column=17;
law_headings=["Article"]}))))
in
{argmax_out = argmax_; argmin_out = argmin_}

View File

@ -0,0 +1,258 @@
# This file has been generated by the Catala compiler, do not edit!
from .catala import *
from typing import Any, List, Callable, Tuple
from enum import Enum
class S:
def __init__(self, id: Integer, income: Money) -> None:
self.id = id
self.income = income
def __eq__(self, other: object) -> bool:
if isinstance(other, S):
return (self.id == other.id and self.income == other.income)
else:
return False
def __ne__(self, other: object) -> bool:
return not (self == other)
def __str__(self) -> str:
return "S(id={},income={})".format(self.id, self.income)
class AOut:
def __init__(self, x_out: List[S]) -> None:
self.x_out = x_out
def __eq__(self, other: object) -> bool:
if isinstance(other, AOut):
return (self.x_out == other.x_out)
else:
return False
def __ne__(self, other: object) -> bool:
return not (self == other)
def __str__(self) -> str:
return "AOut(x_out={})".format(self.x_out)
class AIn:
def __init__(self, x_in: Callable[[Unit], (List[S])]) -> None:
self.x_in = x_in
def __eq__(self, other: object) -> bool:
if isinstance(other, AIn):
return (self.x_in == other.x_in)
else:
return False
def __ne__(self, other: object) -> bool:
return not (self == other)
def __str__(self) -> str:
return "AIn(x_in={})".format(self.x_in)
class BOut:
def __init__(self, argmax_out: S, argmin_out: S) -> None:
self.argmax_out = argmax_out
self.argmin_out = argmin_out
def __eq__(self, other: object) -> bool:
if isinstance(other, BOut):
return (self.argmax_out == other.argmax_out and
self.argmin_out == other.argmin_out)
else:
return False
def __ne__(self, other: object) -> bool:
return not (self == other)
def __str__(self) -> str:
return "BOut(argmax_out={},argmin_out={})".format(self.argmax_out,
self.argmin_out)
class BIn:
def __init__(self, ) -> None:
pass
def __eq__(self, other: object) -> bool:
if isinstance(other, BIn):
return (True)
else:
return False
def __ne__(self, other: object) -> bool:
return not (self == other)
def __str__(self) -> str:
return "BIn()".format()
def a(a_in_1:AIn):
x_2 = a_in_1.x_in
try:
def local_var_5(_:Any):
return x_2(Unit())
def local_var_7(_:Any):
return True
def local_var_9(_:Any):
def local_var_11(_:Any):
def local_var_13(_:Any):
return True
def local_var_15(_:Any):
def local_var_17(_:Any):
def local_var_19(_:Any):
return True
def local_var_21(_:Any):
return [S(id = integer_of_string("0"),
income = money_of_cents_string("0")),
S(id = integer_of_string("1"),
income = (money_of_cents_string("400") +
money_of_cents_string("500"))),
S(id = integer_of_string("2"),
income = (money_of_cents_string("800") *
decimal_of_string("0.65")))]
return handle_default([], local_var_19, local_var_21)
def local_var_23(_:Any):
return False
def local_var_25(_:Any):
raise EmptyError
return handle_default([local_var_17], local_var_23,
local_var_25)
return handle_default([], local_var_13, local_var_15)
def local_var_27(_:Any):
return True
def local_var_29(_:Any):
def local_var_31(_:Any):
def local_var_33(_:Any):
return False
def local_var_35(_:Any):
raise EmptyError
return handle_default([], local_var_33, local_var_35)
def local_var_37(_:Any):
return False
def local_var_39(_:Any):
raise EmptyError
return handle_default([local_var_31], local_var_37,
local_var_39)
return handle_default([local_var_11], local_var_27, local_var_29)
local_var_4 = handle_default([local_var_5], local_var_7, local_var_9)
except EmptyError:
raise NoValueProvided(SourcePosition(filename="tests/test_array/good/aggregation_2.catala_en",
start_line=9, start_column=19, end_line=9, end_column=20,
law_headings=["Article"]))
x_3 = local_var_4
return AOut(x_out = x_3)
def b(b_in_41:BIn):
def local_var_43(_:Unit):
raise EmptyError
a_dot_x_42 = local_var_43
result_46 = a(AIn(x_in = a_dot_x_42))
a_dot_x_47 = result_46.x_out
try:
def local_var_50(_:Any):
def local_var_52(_:Any):
return True
def local_var_54(_:Any):
def local_var_56(_:Any):
def local_var_58(_:Any):
return True
def local_var_60(_:Any):
def local_var_63(m_64:Any):
return (m_64.income +
money_of_cents_string("500"))
predicate_62 = local_var_63
def local_var_65(acc_66:Any, item_67:Any):
if (predicate_62(acc_66) <
predicate_62(item_67)):
return acc_66
else:
return item_67
return list_fold_left(local_var_65,
S(id = - integer_of_string("1"),
income = money_of_cents_string("2000")),
a_dot_x_47)
return handle_default([], local_var_58, local_var_60)
def local_var_68(_:Any):
return False
def local_var_70(_:Any):
raise EmptyError
return handle_default([local_var_56], local_var_68,
local_var_70)
return handle_default([], local_var_52, local_var_54)
def local_var_72(_:Any):
return True
def local_var_74(_:Any):
def local_var_76(_:Any):
def local_var_78(_:Any):
return False
def local_var_80(_:Any):
raise EmptyError
return handle_default([], local_var_78, local_var_80)
def local_var_82(_:Any):
return False
def local_var_84(_:Any):
raise EmptyError
return handle_default([local_var_76], local_var_82, local_var_84)
local_var_49 = handle_default([local_var_50], local_var_72,
local_var_74)
except EmptyError:
raise NoValueProvided(SourcePosition(filename="tests/test_array/good/aggregation_2.catala_en",
start_line=21, start_column=11, end_line=21, end_column=17,
law_headings=["Article"]))
argmin_48 = local_var_49
try:
def local_var_88(_:Any):
def local_var_90(_:Any):
return True
def local_var_92(_:Any):
def local_var_94(_:Any):
def local_var_96(_:Any):
return True
def local_var_98(_:Any):
def local_var_101(m_102:Any):
return (m_102.income * decimal_of_string("2."))
predicate_100 = local_var_101
def local_var_103(acc_104:Any, item_105:Any):
if (predicate_100(acc_104) >
predicate_100(item_105)):
return acc_104
else:
return item_105
return list_fold_left(local_var_103,
S(id = - integer_of_string("1"),
income = money_of_cents_string("0")), a_dot_x_47)
return handle_default([], local_var_96, local_var_98)
def local_var_106(_:Any):
return False
def local_var_108(_:Any):
raise EmptyError
return handle_default([local_var_94], local_var_106,
local_var_108)
return handle_default([], local_var_90, local_var_92)
def local_var_110(_:Any):
return True
def local_var_112(_:Any):
def local_var_114(_:Any):
def local_var_116(_:Any):
return False
def local_var_118(_:Any):
raise EmptyError
return handle_default([], local_var_116, local_var_118)
def local_var_120(_:Any):
return False
def local_var_122(_:Any):
raise EmptyError
return handle_default([local_var_114], local_var_120,
local_var_122)
local_var_87 = handle_default([local_var_88], local_var_110,
local_var_112)
except EmptyError:
raise NoValueProvided(SourcePosition(filename="tests/test_array/good/aggregation_2.catala_en",
start_line=20, start_column=11, end_line=20, end_column=17,
law_headings=["Article"]))
argmax_86 = local_var_87
return BOut(argmax_out = argmax_86, argmin_out = argmin_48)

View File

@ -0,0 +1,3 @@
[RESULT] Computation successful! Results:
[RESULT] x = [0; 1; 2; 3; 4; 5; 6]
[RESULT] y = [0; 1; 2; 3; 4; 5; 6; 7; 8; 9; 10]

View File

@ -0,0 +1,2 @@
[RESULT] Computation successful! Results:
[RESULT] x = [$0.00; $9.00; $5.20]

View File

@ -0,0 +1,3 @@
[RESULT] Computation successful! Results:
[RESULT] y = [$9.00; $5.20]
[RESULT] z = [false; true; true]

View File

@ -0,0 +1,2 @@
[RESULT] Computation successful! Results:
[RESULT] x = [0; 9; 64]

View File

@ -0,0 +1,5 @@
[RESULT] Computation successful! Results:
[RESULT] v = 3
[RESULT] w = true
[RESULT] y = true
[RESULT] z = false

View File

@ -0,0 +1,22 @@
## Article
```catala
declaration scope A:
output x content collection integer
scope A:
definition x equals [0; 4+5; 8*8]
declaration scope B:
a scope A
output v content integer
output w content boolean
output y content boolean
output z content boolean
scope B:
definition v equals number of a.x
definition w equals 64 in a.x
definition y equals exists m in a.x such that m = 9
definition z equals for all m in a.x we have m > 0
```