Reasoning

[View merge.thm]

Click on a command or tactic to see a detailed view of its use.

Type is_o  o -> prop.

Import "perm" with is_o := is_o. [View perm]

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% merge J K L : J union K equals L.
Define merge : olist -> olist -> olist -> prop by
; merge nil nil nil
; merge J K L :=
    exists A JJ LL,
      adj JJ A J /\ adj LL A L /\ merge JJ K LL
; merge J K L :=
    exists A KK LL,
      adj KK A K /\ adj LL A L /\ merge J KK LL
.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Theorem merge_1_is_list : forall J K L, merge J K L -> is_list J.

Theorem merge_2_is_list : forall J K L, merge J K L -> is_list K.

Theorem merge_3_is_list : forall J K L, merge J K L -> is_list L.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Theorem perm_merge_1 : forall J K L JJ,
  merge J K L ->
  perm J JJ ->
  merge JJ K L.

Theorem perm_merge_2 : forall J K L KK,
  merge J K L ->
  perm K KK ->
  merge J KK L.

Theorem perm_merge_3 : forall J K L LL,
  merge J K L ->
  perm L LL ->
  merge J K LL.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Theorem merge_sym : forall J K L,
  merge J K L ->
  merge K J L.

Theorem merge_nil_perm : forall K L,
  merge nil K L -> perm K L.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Theorem merge_adj_1 : forall A JJ J K LL,
  merge JJ K LL -> adj JJ A J -> exists L, adj LL A L /\ merge J K L.

Theorem merge_unadj_1 : forall J K L JJ A,
  merge J K L -> adj JJ A J -> exists LL, adj LL A L /\ merge JJ K LL.

Theorem merge_adj_2 : forall A J KK K LL,
  merge J KK LL -> adj KK A K -> exists L, adj LL A L /\ merge J K L.

Theorem merge_unadj_2 : forall J K L KK A,
  merge J K L -> adj KK A K -> exists LL, adj LL A L /\ merge J KK LL.

Theorem merge_unadj_3 : forall J K L LL A,
  merge J K L -> adj LL A L ->
  (exists JJ, adj JJ A J /\ merge JJ K LL)
  \/ (exists KK, adj KK A K /\ merge J KK LL).

%% some simple consequences

Theorem merge_invert_1 : forall A JJ J K LL L,
  merge J K L ->
  adj JJ A J ->
  adj LL A L ->
  merge JJ K LL.

Theorem merge_invert_2 : forall A J KK K LL L,
  merge J K L ->
  adj KK A K ->
  adj LL A L ->
  merge J KK LL.

Theorem merge_move_12 : forall A JJ J KK K L,
  adj JJ A J ->
  adj KK A K ->
  merge J KK L ->
  merge JJ K L.

Theorem merge_move_21 : forall A JJ J KK K L,
  adj JJ A J ->
  adj KK A K ->
  merge JJ K L ->
  merge J KK L.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Theorem add_to_merge_right : forall A J K KK L,
  adj KK A K ->
  merge J KK L ->
  exists M, merge J K M /\ adj L A M.

Theorem add_to_merge_left : forall A J JJ K L,
  adj JJ A J ->
  merge JJ K L ->
  exists M, merge J K M /\ adj L A M.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Theorem merge_nil_equal : forall L,
  is_list L -> merge nil L L.

Theorem merge_exists : forall J K,
  is_list J -> is_list K ->
  exists L, merge J K L.

Theorem merge_head_lemma : forall L A,
  is_o A -> is_list L -> merge L (A :: nil) (A :: L).

% Note: the contrary is not true, since adj is order-sensitive
Theorem adj_implies_merge : forall L J A,
  adj L A J -> merge L (A :: nil) J.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% Associativity

Theorem merge_assoc : forall J K L JK KL JKL1 JKL2,
  merge J K JK -> merge K L KL ->
  merge J KL JKL1 -> merge JK L JKL2 ->
  perm JKL1 JKL2.

Theorem change_merge_order : forall J K L JK KL JKL,
  merge JK L JKL -> merge J K JK -> merge K L KL ->
  merge J KL JKL.

Theorem change_merge_order2 : forall J K JK L KL JKL,
  merge J K JK -> merge K L KL -> merge J KL JKL ->
  merge JK L JKL.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Theorem merge_perm_det : forall J K L1 L2,
  merge J K L1 ->
  merge J K L2 ->
  perm L1 L2.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

Theorem merge_preserves_perm_lem : forall L LL J K,
  is_list J ->
  merge L J K ->
  merge LL J K ->
  perm L LL.

Theorem merge_preserves_perm : forall L LL J K,
  merge L J K ->
  merge LL J K ->
  perm L LL.

% This needs a better name...
Theorem merge_sub : forall J K L JK JL JKL,
  merge J K JK ->
  merge JK L JKL ->
  merge JL K JKL ->
  merge J L JL.

Theorem merge_to_adj : forall J L A,
  merge J (A :: nil) L ->
  exists JJ, perm J JJ /\ adj JJ A L.

Theorem merge_same_result_diff : forall J A K B L,
  merge J (A :: nil) L ->
  merge K (B :: nil) L ->
  (A = B /\ perm J K) \/
  exists KK, merge KK (A :: nil) K.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% subsets via merge

Define subset : olist -> olist -> prop by
  subset J L := exists K, merge J K L.

Theorem subset_1_is_list : forall J K, subset J K -> is_list J.

Theorem subset_2_is_list : forall J K, subset J K -> is_list K.