Skip to content

Commit c93d1e9

Browse files
committed
Implement and test find list function
1 parent 16e4ce1 commit c93d1e9

File tree

2 files changed

+80
-2
lines changed

2 files changed

+80
-2
lines changed

src/structuredPoly.ml

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,23 @@ let binary_bool_list_op =
254254
[ Intersection [ (binary_poly_bool, binary_list_bool) ] ])
255255
binary_poly_bool_op binary_list_bool_op
256256

257+
(* Represents `X -> Bool`, the first part of the find function *)
258+
let poly_bool_op = func_type ([ UnivTypeVar 0 ], bool_type.union)
259+
260+
(* Represents `X List -> X | None`, the second half of the find function *)
261+
let list_extract_op =
262+
map_type
263+
(fun list ->
264+
[ Intersection [ (list, UnivTypeVar 0 :: none_label.stype.union) ] ])
265+
polymoprhic_list_type.full
266+
267+
(* Represents `(X -> Bool) -> X List -> X | None`, the type of the find function *)
268+
let find_op =
269+
map_type2
270+
(fun poly_bool list_extract ->
271+
[ Intersection [ (poly_bool, list_extract) ] ])
272+
poly_bool_op list_extract_op
273+
257274
(* Polymoprhic function that prepends an element of arbitrary tpye to a list of that type *)
258275
let cons =
259276
typed_term
@@ -328,6 +345,7 @@ let fix_map =
328345
fix (func_type ([ UnivTypeVar 1 ], [ UnivTypeVar 0 ])) list_transform_op
329346

330347
let fix_equal = fix binary_poly_bool_op binary_list_bool_op
348+
let fix_find = fix poly_bool_op list_extract_op
331349

332350
let length =
333351
typed_term
@@ -621,8 +639,39 @@ let equal =
621639
] );
622640
])))
623641

642+
let find =
643+
typed_term
644+
(UnivQuantifier
645+
(fix_find
646+
(Abstraction
647+
[
648+
( find_op,
649+
Abstraction
650+
[
651+
( poly_bool_op,
652+
Abstraction
653+
[
654+
(empty_list.stype, none_label.term);
655+
( polymoprhic_list_type.non_empty,
656+
Application
657+
( Abstraction
658+
[
659+
( true_lambda.stype,
660+
Application (head_poly.term, Variable 1)
661+
);
662+
( false_lambda.stype,
663+
binary_apply (Variable 3) (Variable 2)
664+
(Application
665+
(tail_poly.term, Variable 1)) );
666+
],
667+
Application
668+
( Variable 1,
669+
Application (head_poly.term, Variable 0) )
670+
) );
671+
] );
672+
] );
673+
])))
674+
624675
(* List functions we should implement:
625-
* equal
626-
* find (return element and/or index)
627676
* flatten
628677
*)

test/structuredLambdaPoly.ml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ let fold_int_int =
205205
let every_int = typed_term (UnivApplication (every.term, ind_integer))
206206
let exists_int = typed_term (UnivApplication (exists.term, ind_integer))
207207
let equal_int = typed_term (UnivApplication (equal.term, ind_integer))
208+
let find_int = typed_term (UnivApplication (find.term, ind_integer))
208209

209210
let true_predicate =
210211
typed_term
@@ -696,3 +697,31 @@ let () =
696697
(trinary_apply equal_int.term is_equal.term simple_integer_list.term
697698
incrementing_integer_list.term)
698699
false_lambda.term)
700+
701+
let () =
702+
test "Find has the right type"
703+
(is_subtype find.stype (map_type univ_quantify_union find_op))
704+
705+
let () =
706+
test "Find in empty list returns None"
707+
(evaluates_to
708+
(binary_apply find_int.term is_even.term empty_list.term)
709+
none_label.term)
710+
711+
let () =
712+
test "Find is_even in simple integer list returns 2"
713+
(evaluates_to
714+
(binary_apply find_int.term is_even.term simple_integer_list.term)
715+
(num_term 2))
716+
717+
let () =
718+
test "Find is_positive in simple integer list returns 1"
719+
(evaluates_to
720+
(binary_apply find_int.term
721+
(Abstraction
722+
[
723+
(ind_positive_number, true_lambda.term);
724+
(ind_non_positive_number, false_lambda.term);
725+
])
726+
simple_integer_list.term)
727+
(num_term 1))

0 commit comments

Comments
 (0)