The operation $PatternMatch$ takes a syntactic pattern and a semantic value as
input, and returns the setof possible block environments. In each block
environment the identifiers defined in the input pattern are bound to
the corresponding value from the input semantic value. An empty returnset
indicates that no matching can be performed.
\begin{vdm_al} operations
PatternMatch : Pattern * VAL ==> setof BlkEnv
PatternMatch (pat_p, val_v) == casestrue:
(is_PatternName(pat_p)) -> let mk_PatternName(id) = pat_p in return { MkBlkEnv(id, val_v) },
(is_MatchVal(pat_p)) -> let lval = LooseEvalExpr(pat_p.val) in
(forall mk_(v,m) inset lval do if v = val_v thenreturn { MkEmptyBlkEnv()}; return {}),
(is_SetEnumPattern(pat_p)) -> MatchSetEnumPattern(pat_p, val_v),
(is_SetUnionPattern(pat_p)) -> MatchSetUnionPattern(pat_p, val_v), others -> error end;
\end{vdm_al}
Concerning match values it should be noted that the definition given
above isnot entirely correct. In fact the model which are used for
the model should be returned as well, but we have abstracted away from
this for the moment because that would change the usage of the
$PatternMatch$ operation all places. Naturally, the model assumptions
used in the match value should be taken into account in the expression
evaluation function where the pattern occurs.
Note that the $MkBlkEnv$ operation takes into account whether we
are currently matching inside a function body, andif so adds the
relevant information to the unique identifier which is used in the
block environment.
This operation returns the setofall possible binding environments.
The main condition for matching a set enumeration pattern is that the
value is a set value andthen that the cardinality of the value
corresponds to the number of elements in the set enumeration pattern. We
first create the setofall permutations of the input semantic value.
The distributed unionofall matches of the input pattern list with
the elements from the permutation is returned when a successful
match is found.
\begin{vdm_al}
MatchSetUnionPattern : SetUnionPattern * VAL ==> setof BlkEnv
MatchSetUnionPattern ( mk_SetUnionPattern(lp_p, rp_p), val_v) ==
( dcl envres_sl : setof BlkEnv := {}; if is_SET(val_v) thenlet mk_SET(val_sv) = val_v in
( forall mk_(setl_sv, setr_sv) inset
{ mk_(setl_sv,setr_sv) |
setl_sv ,setr_sv insetpower val_sv &
(setl_sv union setr_sv = val_sv ) and
(setl_sv inter setr_sv = {}) } do let envl_s = PatternMatch(lp_p, mk_SET(setl_sv)),
envr_s = PatternMatch(rp_p, mk_SET(setr_sv)) in if envl_s <> {} and envr_s <> {} thenlet tmpenv = { CombineBlkEnv(tmp1, tmp2) |
tmp1 inset envl_s, tmp2 inset envr_s } in
envres_sl := envres_sl union UnionMatch(tmpenv); return envres_sl
) elsereturn {}
);
\end{vdm_al}
In the case of a setunion pattern, we first create all pairs ofset values, for which the unionis equal to the original input set value, but
are still disjoint. For each pair, we create two sets of binding
environments. These are combined, and inserted into the resulting setof
binding environments after duplicate entries are removed\footnote{Here
it is worth noting that the disjointness criterion which has been
used for both set enumeration patterns andforset comprehension
patterns no longer conforms to the semantics given in the
standard. However, we have decided to retain this here because we have notyet been able to find any examples where one would like such
patterns tobe non-disjoint.}. $UnionMatch$ also ensures that pattern
identifiers which occur multiple times are consistently bound to the
same value everywhere.
\begin{vdm_al}
MatchLists : seqof Pattern * seqof VAL ==> setof BlkEnv
MatchLists (els_lp, val_lv) == let tmp_ls = [ PatternMatch(els_lp(i), val_lv(i)) |
i insetinds els_lp ] in if {} notinsetelems tmp_ls thenlet perm_s = SeqOfSetOf2SetOfSeqOf(tmp_ls) in
UnionMatch({ conc l | l inset perm_s }) elsereturn {};
\end{vdm_al}
For each element from the input pattern sequence, we create a setof
binding environments by matching the pattern with the corresponding element from the input value sequence. Ifall elements match, each setof
environments from the sequence $tmp-ls$ is merged into a setwith one
single environment.