cpsa-4.4.1: coq/Match.v
(* Matching
Copyright (c) 2021 The MITRE Corporation
This program is free software: you can redistribute it and/or
modify it under the terms of the BSD License as published by the
University of California. *)
(** * Matching
A term [x] matches [y] if there is a substitution [sb] such that
applying [sb] to [x] gives [y]. The match function defined within
computes substitutions. *)
Require Import String Monad Alg Role.
Import List.ListNotations.
Open Scope list_scope.
(** printing <- #←# *)
(** A substitution *)
Definition sbst: Set := list (var * alg).
Definition extend_term (sb: sbst) (v: var) (x: alg): option sbst :=
match lookup v sb with
| None => Some ((v, x) :: sb)
| Some y =>
if alg_dec x y then
Some sb
else (* Term clash! *)
None
end.
Definition match_skey (sb: sbst) (x y: skey): option sbst :=
match x, y with
| Sv v, w => extend_term sb v (Sk w)
| Lt v w, Lt x y =>
sb <- extend_term sb v (Nm x);;
extend_term sb w (Nm y)
| _, _ => None
end.
Definition match_akey (sb: sbst) (x y: akey): option sbst :=
match x, y with
| Av v, w => extend_term sb v (Ak w)
| Pb v, Pb w => extend_term sb v (Nm w)
| Pb2 s v, Pb2 t w =>
if eqb s t then
extend_term sb v (Nm w)
else
None
| _, _ => None
end.
(** Definition of matching *)
Fixpoint match_term (sb: sbst) (x y: alg): option sbst :=
match x, y with
| Tx v, Tx w => extend_term sb v (Tx w)
| Dt v, Dt w => extend_term sb v (Dt w)
| Nm v, Nm w => extend_term sb v (Nm w)
| Sk v, Sk w => match_skey sb v w
| Ak v, Ak w => match_akey sb v w
| Ak (Av v), Ik w => extend_term sb v (Ik w)
| Ik v, Ik w => match_akey sb v w
| Ik (Av v), Ak w => extend_term sb v (Ik w)
| Ch v, Ch w => extend_term sb v (Ch w)
| Mg v, w => extend_term sb v w
| Tg s, Tg t =>
if eqb s t then
Some sb
else
None
| Pr v w, Pr x y =>
sb <- match_term sb v x;;
match_term sb w y
| En v w, En x y =>
sb <- match_term sb v x;;
match_term sb w y
| Hs v, Hs w => match_term sb v w
| _, _ => None
end.
(** ** Role Homomorphism
See if [x] matches one item in [ys]. *)
Definition match_evt (sb: sbst) (x y: evt): option sbst :=
match x, y with
| Sd c x, Sd d y =>
sb <- match_term sb (Ch c) (Ch d);;
match_term sb x y
| Rv c x, Rv d y =>
sb <- match_term sb (Ch c) (Ch d);;
match_term sb x y
| _, _ => None
end.
Fixpoint match_trace (sb: sbst) (xs ys: list evt): option sbst :=
match xs, ys with
| [], [] => Some sb
| x :: xs, y :: ys =>
sb <- match_evt sb x y;;
match_trace sb xs ys
| _, _ => None
end.
Fixpoint match_list (sb: sbst) (xs ys: list alg): option sbst :=
match xs, ys with
| [], [] => Some sb
| x :: xs, y :: ys =>
sb <- match_term sb x y;;
match_list sb xs ys
| _, _ => None
end.
Fixpoint match_one (ys: list alg) (sb: sbst) (x: alg): option sbst :=
match ys with
| [] => None
| y :: ys =>
match match_term sb x y with
| Some sb => Some sb
| None => match_one ys sb x
end
end.
Definition match_uniqs (sb: sbst) (xs ys: list alg): option sbst :=
fold_m (match_one ys) sb xs.
(** There exists a homomorphism from [x] to [y] iff the result is not
[None]. *)
Definition homomorphism (x y: role): option sbst :=
sb <- match_trace [] (trace x) (trace y);;
sb <- match_uniqs sb (uniqs x) (uniqs y);;
sb <- match_list sb (inputs x) (inputs y);;
match_list sb (outputs x) (outputs y).