Hi Alex, Ice, вт, 29 сент. 2020 г. в 10:52, ice.r...@gmail.com <ice.redm...@gmail.com>:
> I was able to get rid of this error by replacing *reused_l* with *l_ucap > >= r_len *and* l_ucap < r_len* So constraint solver didn't liked > introducing reused_l. Is there a proper way to introduce a bool constraint, > that either true in some case or false otherwise? Something like > ``` > ... > [reused_l: bool (l_ucap >= r_len) ] > ... > ``` > ? > Ice, this is not supported, unfortunately. It's a step in the right direction, I think. But you could return a boolean with this index in the proof-part of function return type. Alex, you could also try encoding this state transition using a dataprop. You'd require 2 indexes per static variable (one for the value of the variable at entry into function [append], and another for the value of the variable after the function [append] exits). You'd have one branch for the cause of reuse (guarded by l_ucap>=r_len), and another branch for the opposite case (guarded by the negation, i.e. l_ucap < r_len). That's quite tedious, and since some variables don't change we don't have to add them to indexes. dataprop append_p ( l_len:int, l_offset:int, l_cap:int, l_ucap:int, l_refcnt: int, l_dynamic: bool, l_p:addr, r_len:int, (*rl_ucap:*)int,(*rl_refcnt:*)int,(*len*)int,(*offset:*)int,(*cap:*)int,(*ucap:*)int,(*refcnt:*)int, (*dynamic:*)bool,(*l:*)addr ) = | {l_ucap >= r_len} append_p_reused of (l_len, l_offset, l_cap, l_ucap, l_refcnt, l_dynamic, l_p, r_len, 0, l_refcnt + 1, l_len + r_len, l_offset, l_cap, l_ucap - r_len, 1, l_dynamic, l_p) | {l:addr | l_ucap < r_len; l != l_p} append_p_fresh of (l_len, l_offset, l_cap, l_ucap, l_refcnt, l_dynamic, l_p, r_len, l_ucap, l_refcnt, l_len + r_len, 0, l_len + r_len, 0, 0, true, l) The type of append then becomes something like this: fn append {l_len, l_offset, l_cap, l_ucap, l_refcnt: nat}{l_dynamic:bool}{l_p:addr} {r_len, r_offset, r_cap, r_ucap, r_refcnt: nat}{r_dynamic:bool}{r_p:addr} ( l: !Bytestring_vtype(l_len, l_offset, l_cap, l_ucap, l_refcnt, l_dynamic, l_p) >> Bytestring_vtype( l_len, l_offset, l_cap, rl_ucap, rl_refcnt, l_dynamic, l_p) , r: !Bytestring_vtype(r_len, r_offset, r_cap, r_ucap, r_refcnt, r_dynamic, r_p) ): #[rl_ucap:int; rl_refcnt:int;len:int;offset:int;cap:int; ucap:int; refcnt:int; dynamic:bool; l:addr] ( append_p (l_len, l_offset, l_cap, l_ucap, l_refcnt, l_dynamic, l_p, r_len, rl_ucap,rl_refcnt,offset,cap,ucap,refcn, dynamic,l) | Bytestring_vtype( len, offset, cap, ucap, refcnt, dynamic, l) ) There might be some bugs here, haven't tested it, but I think this could be made workable. > вторник, 29 сентября 2020 г. в 07:02:02 UTC, ice.r...@gmail.com: > >> Hi, >> I am starting to think, that my code's goal is to explore corner cases of >> type checker :) >> >> This time, I have this error: >> ``` >> /data/devel/ats2/bytestring/DATS/bytestring_flat.dats: 8313(line=299, >> offs=8) -- 8316(line=299, offs=11): error(3): this constraint cannot be >> s3exp2icnstr-handled: s3e0 = S3Eerr(S2RTbas(S2RTBASpre(bool))) >> ``` >> with this code >> SATS file: >> ``` >> (* creates new bytestring with content of r appended to l. does not >> consumes l and r >> in case if 'l' has enough unused capacity to fit 'r', it will copy >> content of 'r' into this unused space, incrementing reference counter of l >> and result >> *) >> fn >> append >> {l_len, l_offset, l_cap, l_ucap, l_refcnt: >> nat}{l_dynamic:bool}{l_p:addr} >> {r_len, r_offset, r_cap, r_ucap, r_refcnt: >> nat}{r_dynamic:bool}{r_p:addr} >> ( l: !Bytestring_vtype(l_len, l_offset, l_cap, l_ucap, l_refcnt, >> l_dynamic, l_p) >> Bytestring_vtype( l_len, l_offset, l_cap, rl_ucap, >> rl_refcnt, l_dynamic, l_p) >> , r: !Bytestring_vtype(r_len, r_offset, r_cap, r_ucap, r_refcnt, >> r_dynamic, r_p) >> ): >> #[reused_l: bool | (l_ucap >= r_len && reused_l == true) || reused_l == >> false] >> #[rl_ucap: nat | (reused_l && rl_ucap == 0) || (reused_l == false && >> rl_ucap == l_ucap)] >> #[rl_refcnt:nat | (reused_l && rl_refcnt == l_refcnt + 1) || (reused_l >> == false && rl_refcnt == l_refcnt)] >> #[offset:nat | (reused_l && offset == l_offset) || (reused_l == false >> && offset == 0)] >> #[cap:nat | (reused_l && cap == l_cap) || (reused_l == false && cap == >> l_len + r_len)] >> #[ucap:nat | (reused_l && ucap == l_ucap - r_len) || (reused_l == false >> && ucap == 0)] >> #[refcnt:nat | (reused_l && refcnt == 1) || (reused_l == false && >> refcnt == 0)] >> #[dynamic:bool | (reused_l && dynamic == l_dynamic) || (reused_l == >> false && dynamic == true) ] >> #[l:addr | (reused_l && l == l_p) || (reused_l == false && l != l_p) ] >> Bytestring_vtype( l_len+r_len, offset, cap, ucap, refcnt, dynamic, l) >> >> (* the same as append, but consumes arguments in order to make caller's >> code clear from bunch of val's and free() >> *) >> fn >> appendC >> {l_len, l_offset, l_cap, l_ucap: nat}{l_dynamic:bool}{l_p:addr} >> {r_len, r_offset, r_cap, r_ucap: nat}{r_dynamic:bool}{r_p:addr} >> ( l: Bytestring_vtype(l_len, l_offset, l_cap, l_ucap, 0, l_dynamic, l_p) >> , r: Bytestring_vtype(r_len, r_offset, r_cap, r_ucap, 0, r_dynamic, r_p) >> ): >> >> >> >> >> >> >> * [reused_l: bool | (l_ucap >= r_len && reused_l == true) || reused_l == >> false] [offset:nat | (reused_l && offset == l_offset) || (reused_l && >> offset == 0)] [cap:nat | (reused_l && cap == l_cap) || (cap == l_len + >> r_len)] [ucap:nat | (reused_l && ucap == l_ucap - r_len) || (ucap == 0)] >> [dynamic:bool | (reused_l && dynamic == l_dynamic) || dynamic == true ] >> [l:addr | (reused_l && l == l_p) || (reused_l == false && l != l_p) ]* >> Bytestring_vtype( l_len+r_len, offset, cap, ucap, 0, dynamic, l) >> ``` >> >> DATS file: >> ``` >> implement appendC( l, r) = >> let >> val res = append( l, r) >> val () = free( r) >> in >> if isnot_shared res (* bool (refcnt == 0), ie 5's argument of >> Bytestring_vtype *) >> * then res where { (*line 299 is here *)* >> val () = free l >> } >> else res where { val () = free( l, res) } (* consumes l, decrease recnt >> of res *) >> end >> ``` >> I assume, that compiler has issues with some of bold constraints of >> appendC function, but I am not sure as well as I am not sure how to debug >> it other than changing constraints one by one >> > -- > You received this message because you are subscribed to the Google Groups > "ats-lang-users" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to ats-lang-users+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/ats-lang-users/c88cedd9-dadb-43cb-a7d4-19e8e77774ean%40googlegroups.com > <https://groups.google.com/d/msgid/ats-lang-users/c88cedd9-dadb-43cb-a7d4-19e8e77774ean%40googlegroups.com?utm_medium=email&utm_source=footer> > . > -- Cheers, Artyom Shalkhakov -- You received this message because you are subscribed to the Google Groups "ats-lang-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to ats-lang-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/ats-lang-users/CAKO6%3Dqgt85c2q0W%3Dws0Y7SW-iCQMyNLCVN%2B3wpxs4TdCjUxAvA%40mail.gmail.com.