Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Labeled Tuples #1235

Draft
wants to merge 92 commits into
base: dev
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
3d2a351
labeled tuple rewrite
WondAli Feb 23, 2024
6889f4f
Merge branch 'dev' into labeled-tuple-rewrite
WondAli Feb 23, 2024
c137ded
working dot operator + bug fixes to precedence
WondAli Mar 23, 2024
5af500f
may need to revert some tuplabel code since no longer consistent with…
WondAli Mar 31, 2024
9927605
allow for unmatched labels in one direction
WondAli Apr 13, 2024
55500e6
updated casting for labels
WondAli Apr 22, 2024
f08c114
left-associativity for dot operator
WondAli Apr 25, 2024
7ab1470
dot now treats labels as tuples of size 1
WondAli Apr 25, 2024
1cdeb3a
multiple bug fixes and implemented labels as function arguments. TODO…
WondAli Apr 28, 2024
0598c9c
code cleanup, quality improvement. Also fixes to casting (mostly)
WondAli Jun 7, 2024
b3e7c84
casting bug fix
WondAli Jun 7, 2024
dfdf051
merged with dev
WondAli Jun 7, 2024
07275db
minor changes to dot in statics and matching
WondAli Jun 25, 2024
44841b8
standalone labels as singleton tuples + shifting error handling for u…
WondAli Jun 28, 2024
56d9a50
fixed bug concerning rearranging function arguments
WondAli Jul 3, 2024
3d294dd
documentation in progress
WondAli Jul 30, 2024
cbe3125
merge complete
WondAli Jul 31, 2024
e0952df
renamed some variables to be more accurate
WondAli Aug 8, 2024
bf1137c
dot operator update
WondAli Aug 12, 2024
9ab0f49
dot operator static fixes
WondAli Aug 16, 2024
db194f8
Creation of Label term, bug fixes, documentation updates
WondAli Aug 23, 2024
c20706a
fixes to labeled expressions as singleton tuples
WondAli Aug 24, 2024
fe24986
minor test_elaboration update
WondAli Aug 24, 2024
773fa9b
singleton tuple fixes
WondAli Aug 27, 2024
e76f5e2
fix statics to check for mismatched labels
WondAli Aug 27, 2024
a802eb7
fix to let elaboration so that dot operators operate on annotated typ…
WondAli Aug 28, 2024
65eec8e
merge (not working)
WondAli Sep 12, 2024
4753f3f
fix to precedence and cast ground_caes_of
WondAli Sep 13, 2024
cae4bb5
elaborator fixes
WondAli Sep 13, 2024
bc22754
updated parser for dot operator
WondAli Sep 13, 2024
e810400
debug
7h3kk1d Sep 20, 2024
840f06f
Temp commit
7h3kk1d Sep 21, 2024
58fc12c
Add rearrange2
7h3kk1d Sep 21, 2024
2b1eda8
I got some version of elaboration working
7h3kk1d Sep 21, 2024
2be5a46
Fix formatting
7h3kk1d Sep 21, 2024
f7a2666
Cleanup
7h3kk1d Sep 23, 2024
a2c34df
Revert makefile changes
7h3kk1d Sep 23, 2024
50536fe
Cleanup debugging code
7h3kk1d Sep 23, 2024
4226bb4
More cleanup
7h3kk1d Sep 23, 2024
8eef13c
Got a version of evaluation to work
7h3kk1d Sep 23, 2024
998caeb
Stop elaborating labels in Dot
7h3kk1d Sep 27, 2024
000b853
updates to elaboration, label extraction, ap in progress
WondAli Sep 27, 2024
76247f0
merged with labeled-tuple-rewrite
WondAli Sep 27, 2024
8379dec
Missing labeled tuple labels elboration (#1399)
WondAli Sep 27, 2024
d5dfa8f
cleaned LabeledTuple util file
WondAli Sep 27, 2024
7d707c9
Rearranging does not occur past elaboration. Functions reworked to al…
WondAli Sep 29, 2024
20c51f9
Add support for fast_equal on TupLabel expressions
7h3kk1d Oct 2, 2024
49c11d9
Add test for elaboration adding labels to labeled tuples
7h3kk1d Oct 2, 2024
38b10c1
Inline expectation
7h3kk1d Oct 2, 2024
c315caa
Fix typos
7h3kk1d Oct 2, 2024
5707718
Add test for rearranging labels during elaboration
7h3kk1d Oct 2, 2024
e4fb061
Merge remote-tracking branch 'origin/dev' into labeled-tuple-rewrite
7h3kk1d Oct 2, 2024
8d6528e
Add test for labeled tuple projection evaluation
7h3kk1d Oct 2, 2024
a5c83bc
Add statics test for labeled parameter in function
7h3kk1d Oct 2, 2024
f4d778e
Added tests to assure that types are inconsistent when unlabeled vari…
7h3kk1d Oct 4, 2024
32173ea
removed function implicit labelling and rearranging in type consisten…
WondAli Oct 4, 2024
318cfb3
Add basic elaboration tests for singleton tuples
7h3kk1d Oct 11, 2024
c8ef191
Modify singleton labeled tuple elaboration
7h3kk1d Oct 11, 2024
22cd8d6
Add parser tests for singleton tuples
7h3kk1d Oct 11, 2024
f04c976
Wrap all tuplabels in tuples in parser
7h3kk1d Oct 11, 2024
78e817c
Remove is_contained logic
7h3kk1d Oct 11, 2024
7008809
More tests
7h3kk1d Oct 13, 2024
59ff548
Add assertions that there's no static errors in static tests
7h3kk1d Oct 13, 2024
158a62d
Merge branch 'dev' into labeled-tuple-rewrite
7h3kk1d Oct 13, 2024
0669d9c
Ensure more tests are fully consistent
7h3kk1d Oct 13, 2024
c27642b
Stop recalculating statics in tests
7h3kk1d Oct 13, 2024
bcd9fe2
Add support for displaying TupLabel with label and type in view_ty fu…
7h3kk1d Oct 13, 2024
926c5c7
Add labeled tuples doc page
7h3kk1d Oct 14, 2024
5f790cb
revert scratch file
7h3kk1d Oct 14, 2024
39cbba1
Revert init.ml
7h3kk1d Oct 14, 2024
b242321
Add sdocumentation page for labeled tuples
7h3kk1d Oct 14, 2024
de85c69
Tests for multiple labels
7h3kk1d Oct 14, 2024
3c36566
Update Makefile to include dev profile in watch-test
7h3kk1d Oct 14, 2024
72b4cac
Add test case for singleton labeled tuple adding label
7h3kk1d Oct 14, 2024
828da51
Make labeled tuple not need parens in display
7h3kk1d Oct 14, 2024
7688a2b
Add test case for let statement that adds labels during elaboration
7h3kk1d Oct 14, 2024
c86e5f0
Add support for lifting single values into a singleton labeled tuple …
7h3kk1d Oct 14, 2024
dac5119
Refmt
7h3kk1d Oct 14, 2024
3420d2c
Additional test for singleton labels
7h3kk1d Oct 14, 2024
1fa320c
SIngleton labels kind of work
7h3kk1d Oct 14, 2024
c87048d
Remove singleton product from type view
7h3kk1d Oct 14, 2024
01f84c5
Fix the duplicate singleton label statics
7h3kk1d Oct 15, 2024
e018126
Fix stack overflow
7h3kk1d Oct 15, 2024
11804a2
Fix warning in test statics
7h3kk1d Oct 15, 2024
523177e
First attempt singleton labeled tuple elaboration
7h3kk1d Oct 15, 2024
c4db0d0
Remove debug comment
7h3kk1d Oct 16, 2024
03208ff
Fix test
7h3kk1d Oct 16, 2024
0f8521a
More singleton label elaborator fixes
7h3kk1d Oct 16, 2024
1bee9bb
Update init
7h3kk1d Oct 18, 2024
e66dd80
Add tests for singleton labeled argument function application
7h3kk1d Oct 18, 2024
b42c613
Progress on elaborating singleton tuples with mismatched labels
7h3kk1d Oct 21, 2024
9a918ef
Fix warnings
7h3kk1d Oct 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
295 changes: 295 additions & 0 deletions src/haz3lcore/LabeledTuple.re
Original file line number Diff line number Diff line change
@@ -0,0 +1,295 @@
open Util;

exception Exception;

[@deriving (show({with_path: false}), sexp, yojson)]
type t = string;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this type be label instead of LabeledTuple.t? I believe it's just used for the labels.


let equal: (option((t, 'a)), option((t, 'b))) => bool =
(left, right) => {
switch (left, right) {
| (Some((s1, _)), Some((s2, _))) => String.equal(s1, s2)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personal note: It would be great if we had map2 from https://ocaml.janestreet.com/ocaml-core/109.20.00/doc/core/Option.html

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This exists in OptUtil

| (_, _) => false
};
};

let length = String.length;

let compare = String.compare;

let find_opt: ('a => bool, list('a)) => option('a) = List.find_opt;

// returns a pair containing a list of option(t) and a list of 'a
let seperate_labels:
('a => option((t, 'a)), list('a)) => (list(option(t)), list('a)) =
(get_label, es) => {
let results =
List.fold_left(
((ls, ns), e) =>
switch (get_label(e)) {
| Some((s1, e)) => (ls @ [Some(s1)], ns @ [e])
| None => (ls @ [None], ns @ [e])
},
([], []),
es,
);
results;
};

// returns ordered list of (Some(string), TupLabel)
// and another of (None, not-TupLabel)
// TODO: Need to check uniqueness earlier
// TODO: Make more efficient
let validate_uniqueness:
('a => option((t, 'a)), list('a)) =>
(bool, list((option(t), 'a)), list('a)) =
(get_label, es) => {
let results =
List.fold_left(
((b, ls, ns), e) =>
switch (get_label(e)) {
| Some((s1, _))
when
b
&& List.fold_left(
(v, l) =>
switch (l) {
| (Some(s2), _) when v => compare(s1, s2) != 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you can just use s1 != s2

| _ => false
},
true,
ls,
) => (
b,
ls @ [(Some(s1), e)],
ns,
)
| None => (b, ls, ns @ [e])
| _ => (false, ls, ns)
},
(true, [], []),
es,
);
results;
};

// Assumes all labels are unique
// filt returns Some(string) if TupLabel or None if not a TupLabel
// returns a permutation of l2 that matches labels in l1
// other labels are in order, even if not matching.
let rearrange:
(
'a => option((t, 'a)),
'b => option((t, 'b)),
list('a),
list('b),
(t, 'b) => 'b
) =>
list('b) =
(get_label1, get_label2, l1, l2, constructor) => {
// TODO: Error handling in case of bad arguments
let (_, l1_lab, _) = validate_uniqueness(get_label1, l1);
let (_, l2_lab, _) = validate_uniqueness(get_label2, l2);
// Second item in the pair is the full tuplabel
let l2_matched =
List.fold_left(
(l2_matched, l1_item) => {
let l2_item =
find_opt(
l2_item => {
switch (l1_item, l2_item) {
| ((Some(s1), _), (Some(s2), _)) => compare(s1, s2) == 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here with s1 == s2

| (_, _) => false
}
},
l2_lab,
);
switch (l2_item) {
| Some(l2_item) => l2_matched @ [l2_item]
| None => l2_matched
};
},
[],
l1_lab,
);
// Second item in the pair is just the element half of the tuplabel
let l2_rem =
List.fold_left(
(l2_rem, item) => {
switch (get_label2(item)) {
| Some((s1, _))
when
List.exists(
l => {
switch (l) {
| (Some(s2), _) => compare(s1, s2) == 0
| _ => false
}
},
l2_matched,
) => l2_rem
| Some((s1, it)) => l2_rem @ [(Some(s1), it)]
| _ => l2_rem @ [(None, item)]
}
},
[],
l2,
);
let rec rearrange_helper =
(
l1: list('x),
l2_matched: list((option(t), 'y)),
l2_rem: list((option(t), 'y)),
)
: list('y) =>
switch (l1) {
| [hd, ...tl] =>
switch (get_label1(hd)) {
| Some((s1, _)) =>
switch (l2_matched) {
| [] =>
switch (l2_rem) {
| [hd2, ...tl2] =>
switch (hd2) {
| (Some(s2), rem_val) =>
[constructor(s2, rem_val)]
@ rearrange_helper(tl, l2_matched, tl2)
| (None, rem_val) =>
[constructor(s1, rem_val)]
@ rearrange_helper(tl, l2_matched, tl2)
}
| [] => raise(Exception)
}
| [hd2, ...tl2] =>
switch (hd2) {
| (Some(s2), l2_val) when compare(s1, s2) == 0 =>
[l2_val] @ rearrange_helper(tl, tl2, l2_rem)
| _ =>
switch (l2_rem) {
| [hd2, ...tl2] =>
switch (hd2) {
| (Some(s2), rem_val) =>
[constructor(s2, rem_val)]
@ rearrange_helper(tl, l2_matched, tl2)
| (None, rem_val) =>
[constructor(s1, rem_val)]
@ rearrange_helper(tl, l2_matched, tl2)
}
| [] => raise(Exception)
}
}
}
| None =>
switch (l2_rem) {
| [(_, hd2), ...tl2] =>
[hd2] @ rearrange_helper(tl, l2_matched, tl2)
| [] => raise(Exception)
}
}
| [] => []
};
rearrange_helper(l1, l2_matched, l2_rem);
};

// Rename and clean this
// Assumes all labels are unique
// filt returns Some(string) if TupLabel or None if not a TupLabel
// In order of operations:
// Checks all labeled pairs in l2 are in l1 and performs f on each pair
// Checks all labeled pairs in l1 are in l2 and performs f on each pair
// Checks remaining None pairs in order and performs f on each pair
let ana_tuple:
(
'b => option((t, 'b)),
'c => option((t, 'c)),
('a, 'b, 'c) => 'a,
'a,
'a,
list('b),
list('c)
) =>
'a =
(get_label1, get_label2, f, accu, accu_fail, l1, l2) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these would be slightly easier to read if the types were on the params as opposed to on the function itself. I'm open to other viewpoints on it though.

let (l1_valid, l1_lab, l1_none) = validate_uniqueness(get_label1, l1);
let (l2_valid, l2_lab, _) = validate_uniqueness(get_label2, l2);
// temporary solution if mess up earlier in tuple, such as make_term
if (!l1_valid || !l2_valid) {
accu_fail;
} else {
// this result represents to accu, and the matched l2 labels
let (accu, l2_labels_matched) =
List.fold_left(
((accu, l2_matched), l1_item) => {
let l2_item =
find_opt(
l2_item => {
switch (l1_item, l2_item) {
| ((Some(s1), _), (Some(s2), _)) => compare(s1, s2) == 0
| (_, _) => false
}
},
l2_lab,
);
switch (l1_item, l2_item) {
| ((_, l1_val), Some((l2_lab, l2_val))) => (
f(accu, l1_val, l2_val),
l2_matched @ [l2_lab],
)
| (_, None) => (accu_fail, l2_matched)
};
},
(accu, []),
l1_lab,
);
// short circuit on failure
if (accu == accu_fail) {
accu_fail;
} else {
// filter l2 to remove matched labels and remove labels
// TODO: Can be optimized
let l2_rem =
List.fold_left(
(l2_rem, item) => {
switch (get_label2(item)) {
| Some((s1, _))
when
List.exists(
l => {
switch (l) {
| Some(s2) => compare(s1, s2) == 0
| _ => false
}
},
l2_labels_matched,
) => l2_rem
| _ => l2_rem @ [item]
}
},
[],
l2,
);
// remaining checks are in order
let accu =
List.fold_left2(
(accu, l1_val, l2_val) => f(accu, l1_val, l2_val),
accu,
l1_none,
l2_rem,
);
accu;
};
};
};

let find_label: ('a => option((t, 'a)), list('a), t) => option('a) =
(filt, es, label) => {
find_opt(
e => {
switch (filt(e)) {
| Some((s, _)) => compare(s, label) == 0
| None => false
}
},
es,
);
};
4 changes: 4 additions & 0 deletions src/haz3lcore/dynamics/Constraint.re
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type t =
| Or(t, t)
| InjL(t)
| InjR(t)
| TupLabel(t, t)
| Pair(t, t);

let rec dual = (c: t): t =>
Expand All @@ -32,6 +33,7 @@ let rec dual = (c: t): t =>
| Or(c1, c2) => And(dual(c1), dual(c2))
| InjL(c1) => Or(InjL(dual(c1)), InjR(Truth))
| InjR(c2) => Or(InjR(dual(c2)), InjL(Truth))
| TupLabel(c1, c2) => TupLabel(dual(c1), dual(c2))
| Pair(c1, c2) =>
Or(
Pair(c1, dual(c2)),
Expand All @@ -55,6 +57,7 @@ let rec truify = (c: t): t =>
| Or(c1, c2) => Or(truify(c1), truify(c2))
| InjL(c) => InjL(truify(c))
| InjR(c) => InjR(truify(c))
| TupLabel(c1, c2) => TupLabel(truify(c1), truify(c2))
| Pair(c1, c2) => Pair(truify(c1), truify(c2))
};

Expand All @@ -74,6 +77,7 @@ let rec falsify = (c: t): t =>
| Or(c1, c2) => Or(falsify(c1), falsify(c2))
| InjL(c) => InjL(falsify(c))
| InjR(c) => InjR(falsify(c))
| TupLabel(c1, c2) => TupLabel(falsify(c1), falsify(c2))
| Pair(c1, c2) => Pair(falsify(c1), falsify(c2))
};

Expand Down
Loading
Loading