238 |
234 |
239 lemma perm_add_raw_rsp[simp]: |
235 lemma perm_add_raw_rsp[simp]: |
240 "x \<approx> y \<Longrightarrow> xa \<approx> ya \<Longrightarrow> perm_add_raw x xa \<approx> perm_add_raw y ya" |
236 "x \<approx> y \<Longrightarrow> xa \<approx> ya \<Longrightarrow> perm_add_raw x xa \<approx> perm_add_raw y ya" |
241 by (simp add: fun_eq_iff perm_add_apply perm_eq_def) |
237 by (simp add: fun_eq_iff perm_add_apply perm_eq_def) |
242 |
238 |
243 lemma [quot_respect]: |
|
244 "(op \<approx> ===> op \<approx> ===> op \<approx>) perm_add_raw perm_add_raw" |
|
245 by (auto intro!: fun_relI simp add: perm_add_raw_rsp) |
|
246 |
|
247 lemma [simp]: |
239 lemma [simp]: |
248 "a \<approx> a \<longleftrightarrow> valid_perm a" |
240 "a \<approx> a \<longleftrightarrow> valid_perm a" |
249 by (simp_all add: perm_eq_def) |
241 by (simp_all add: perm_eq_def) |
250 |
242 |
251 lemma [quot_respect]: "[] \<approx> []" |
|
252 by auto |
|
253 |
|
254 lemmas [simp] = in_respects |
|
255 |
|
256 instantiation gperm :: (type) group_add |
243 instantiation gperm :: (type) group_add |
257 begin |
244 begin |
258 |
245 |
259 quotient_definition "0 :: 'a gperm" is "[] :: ('a \<times> 'a) list" |
246 lift_definition zero_gperm :: "'a gperm" is "[]" by simp |
260 |
247 |
261 quotient_definition "uminus :: 'a gperm \<Rightarrow> 'a gperm" is |
248 lift_definition uminus_gperm :: "'a gperm \<Rightarrow> 'a gperm" is uminus_perm_raw |
262 "uminus_perm_raw :: ('a \<times> 'a) list \<Rightarrow> ('a \<times> 'a) list" |
249 by (auto simp add: fun_eq_iff perm_apply_minus[symmetric] perm_eq_def) |
263 |
250 |
264 quotient_definition "(op +) :: 'a gperm \<Rightarrow> 'a gperm \<Rightarrow> 'a gperm" is |
251 lift_definition plus_gperm :: "'a gperm \<Rightarrow> 'a gperm \<Rightarrow> 'a gperm" is perm_add_raw |
265 "perm_add_raw :: ('a \<times> 'a) list \<Rightarrow> ('a \<times> 'a) list \<Rightarrow> ('a \<times> 'a) list" |
252 by simp |
266 |
253 |
267 definition |
254 definition |
268 minus_perm_def: "(p1::'a gperm) - p2 = p1 + - p2" |
255 minus_perm_def: "(p1::'a gperm) - p2 = p1 + - p2" |
269 |
256 |
270 instance |
257 instance |
271 apply default |
258 apply default |
272 unfolding minus_perm_def |
259 unfolding minus_perm_def |
273 by (partiality_descending, simp add: perm_add_apply perm_eq_def fun_eq_iff valid_perm_add_minus)+ |
260 by (transfer,simp add: perm_add_apply perm_eq_def fun_eq_iff valid_perm_add_minus)+ |
274 |
261 |
275 end |
262 end |
276 |
263 |
277 definition "mk_perm_raw l = (if valid_perm l then l else [])" |
264 definition "mk_perm_raw l = (if valid_perm l then l else [])" |
278 |
265 |
279 quotient_definition "mk_perm :: ('a \<times> 'a) list \<Rightarrow> 'a gperm" |
266 lift_definition mk_perm :: "('a \<times> 'a) list \<Rightarrow> 'a gperm" is "mk_perm_raw" |
280 is "mk_perm_raw" |
267 by (simp add: mk_perm_raw_def) |
281 |
268 |
282 definition "dest_perm_raw p = sort [x\<leftarrow>p. fst x \<noteq> snd x]" |
269 definition "dest_perm_raw p = sort [x\<leftarrow>p. fst x \<noteq> snd x]" |
283 |
|
284 quotient_definition "dest_perm :: ('a :: linorder) gperm \<Rightarrow> ('a \<times> 'a) list" |
|
285 is "dest_perm_raw" |
|
286 |
|
287 lemma [quot_respect]: "(op = ===> op \<approx>) mk_perm_raw mk_perm_raw" |
|
288 by (auto intro!: fun_relI simp add: mk_perm_raw_def) |
|
289 |
270 |
290 lemma distinct_fst_distinct[simp]: "distinct (map fst x) \<Longrightarrow> distinct x" |
271 lemma distinct_fst_distinct[simp]: "distinct (map fst x) \<Longrightarrow> distinct x" |
291 by (induct x) auto |
272 by (induct x) auto |
292 |
273 |
293 lemma perm_apply_in_set: |
274 lemma perm_apply_in_set: |
339 apply (metis in_set_in_dpr3 fun_eq_iff) |
320 apply (metis in_set_in_dpr3 fun_eq_iff) |
340 unfolding dest_perm_raw_def |
321 unfolding dest_perm_raw_def |
341 by (rule sorted_distinct_set_unique) |
322 by (rule sorted_distinct_set_unique) |
342 (simp_all add: distinct_filter valid_perm_def perm_eq_not_eq_same[simplified perm_eq_def, simplified]) |
323 (simp_all add: distinct_filter valid_perm_def perm_eq_not_eq_same[simplified perm_eq_def, simplified]) |
343 |
324 |
344 lemma [quot_respect]: |
325 lift_definition dest_perm :: "('a :: linorder) gperm \<Rightarrow> ('a \<times> 'a) list" |
345 "(op \<approx> ===> op =) dest_perm_raw dest_perm_raw" |
326 is "dest_perm_raw" |
346 by (auto intro!: fun_relI simp add: perm_eq_def) |
327 by (simp add: perm_eq_def) |
347 |
328 |
348 lemma dest_perm_mk_perm[simp]: |
329 lemma dest_perm_mk_perm[simp]: |
349 "dest_perm (mk_perm xs) = sort [x\<leftarrow>mk_perm_raw xs. fst x \<noteq> snd x]" |
330 "dest_perm (mk_perm xs) = sort [x\<leftarrow>mk_perm_raw xs. fst x \<noteq> snd x]" |
350 by (partiality_descending) |
331 by transfer (simp add: dest_perm_raw_def) |
351 (simp add: dest_perm_raw_def) |
|
352 |
332 |
353 lemma valid_perm_filter_id[simp]: |
333 lemma valid_perm_filter_id[simp]: |
354 "valid_perm p \<Longrightarrow> valid_perm [x\<leftarrow>p. fst x \<noteq> snd x]" |
334 "valid_perm p \<Longrightarrow> valid_perm [x\<leftarrow>p. fst x \<noteq> snd x]" |
355 proof (simp (no_asm) add: valid_perm_def, intro conjI) |
335 proof (simp (no_asm) add: valid_perm_def, intro conjI) |
356 show "valid_perm p \<Longrightarrow> distinct (map fst [x\<Colon>'a \<times> 'a\<leftarrow>p . fst x \<noteq> snd x])" |
336 show "valid_perm p \<Longrightarrow> distinct (map fst [x\<Colon>'a \<times> 'a\<leftarrow>p . fst x \<noteq> snd x])" |
395 "valid_perm p \<Longrightarrow> p \<approx> dest_perm_raw p" |
375 "valid_perm p \<Longrightarrow> p \<approx> dest_perm_raw p" |
396 by (simp_all add: dest_perm_raw_eq[symmetric]) |
376 by (simp_all add: dest_perm_raw_eq[symmetric]) |
397 |
377 |
398 lemma mk_perm_dest_perm[code abstype]: |
378 lemma mk_perm_dest_perm[code abstype]: |
399 "mk_perm (dest_perm p) = p" |
379 "mk_perm (dest_perm p) = p" |
400 by (partiality_descending) |
380 by transfer |
401 (auto simp add: mk_perm_raw_def) |
381 (auto simp add: mk_perm_raw_def) |
402 |
382 |
403 instantiation gperm :: (linorder) equal begin |
383 instantiation gperm :: (linorder) equal begin |
404 |
384 |
405 definition equal_gperm_def: "equal_gperm a b \<longleftrightarrow> dest_perm a = dest_perm b" |
385 definition equal_gperm_def: "equal_gperm a b \<longleftrightarrow> dest_perm a = dest_perm b" |
406 |
386 |
407 instance |
387 instance |
408 apply default |
388 apply default |
409 unfolding equal_gperm_def |
389 unfolding equal_gperm_def |
410 by partiality_descending simp |
390 by transfer simp |
411 |
391 |
412 end |
392 end |
413 |
393 |
414 lemma [code abstract]: |
394 lemma [code abstract]: |
415 "dest_perm 0 = []" |
395 "dest_perm 0 = []" |
416 by (partiality_descending) (simp add: dest_perm_raw_def) |
396 by transfer (simp add: dest_perm_raw_def) |
417 |
397 |
418 lemma [code abstract]: |
398 lemma [code abstract]: |
419 "dest_perm (-a) = dest_perm_raw (uminus_perm_raw (dest_perm a))" |
399 "dest_perm (-a) = dest_perm_raw (uminus_perm_raw (dest_perm a))" |
420 by (partiality_descending) (auto) |
400 by transfer auto |
421 |
401 |
422 lemma [code abstract]: |
402 lemma [code abstract]: |
423 "dest_perm (a + b) = dest_perm_raw (perm_add_raw (dest_perm a) (dest_perm b))" |
403 "dest_perm (a + b) = dest_perm_raw (perm_add_raw (dest_perm a) (dest_perm b))" |
424 by (partiality_descending) auto |
404 by transfer auto |
425 |
405 |
426 quotient_definition "gpermute :: 'a gperm \<Rightarrow> 'a \<Rightarrow> 'a" |
406 lift_definition gpermute :: "'a gperm \<Rightarrow> 'a \<Rightarrow> 'a" |
427 is perm_apply |
407 is perm_apply |
428 |
408 by (simp add: perm_eq_def) |
429 lemma [quot_respect]: "(op \<approx> ===> op =) perm_apply perm_apply" |
|
430 by (auto intro!: fun_relI simp add: perm_eq_def) |
|
431 |
409 |
432 lemma gpermute_zero[simp]: |
410 lemma gpermute_zero[simp]: |
433 "gpermute 0 x = x" |
411 "gpermute 0 x = x" |
434 by descending simp |
412 by transfer simp |
435 |
413 |
436 lemma gpermute_add[simp]: |
414 lemma gpermute_add[simp]: |
437 "gpermute (p + q) x = gpermute p (gpermute q x)" |
415 "gpermute (p + q) x = gpermute p (gpermute q x)" |
438 by descending (simp add: perm_add_apply) |
416 by transfer (simp add: perm_add_apply) |
439 |
417 |
440 definition [simp]:"swap_raw a b = (if a = b then [] else [(a, b), (b, a)])" |
418 definition [simp]: "swap_raw a b = (if a = b then [] else [(a, b), (b, a)])" |
441 |
419 |
442 lemma [quot_respect]: "(op = ===> op = ===> op \<approx>) swap_raw swap_raw" |
420 lift_definition gswap :: "'a \<Rightarrow> 'a \<Rightarrow> 'a gperm" is swap_raw |
443 by (auto intro!: fun_relI simp add: valid_perm_def) |
421 by (auto simp add: valid_perm_def) |
444 |
|
445 quotient_definition "gswap :: 'a \<Rightarrow> 'a \<Rightarrow> 'a gperm" |
|
446 is swap_raw |
|
447 |
422 |
448 lemma [code abstract]: |
423 lemma [code abstract]: |
449 "dest_perm (gswap a b) = (if (a, b) \<le> (b, a) then swap_raw a b else swap_raw b a)" |
424 "dest_perm (gswap a b) = (if (a, b) \<le> (b, a) then swap_raw a b else swap_raw b a)" |
450 by (partiality_descending) (auto simp add: dest_perm_raw_def) |
425 by transfer (auto simp add: dest_perm_raw_def) |
451 |
426 |
452 lemma swap_self [simp]: |
427 lemma swap_self [simp]: |
453 "gswap a a = 0" |
428 "gswap a a = 0" |
454 by (partiality_descending, auto) |
429 by transfer simp |
455 |
430 |
456 lemma [simp]: "a \<noteq> b \<Longrightarrow> valid_perm [(a, b), (b, a)]" |
431 lemma [simp]: "a \<noteq> b \<Longrightarrow> valid_perm [(a, b), (b, a)]" |
457 unfolding valid_perm_def by auto |
432 unfolding valid_perm_def by auto |
458 |
433 |
459 lemma swap_cancel [simp]: |
434 lemma swap_cancel [simp]: |
460 "gswap a b + gswap a b = 0" |
435 "gswap a b + gswap a b = 0" |
461 "gswap a b + gswap b a = 0" |
436 "gswap a b + gswap b a = 0" |
462 by (descending, auto simp add: perm_eq_def perm_add_apply)+ |
437 by (transfer, auto simp add: perm_eq_def perm_add_apply)+ |
463 |
438 |
464 lemma minus_swap [simp]: |
439 lemma minus_swap [simp]: |
465 "- gswap a b = gswap a b" |
440 "- gswap a b = gswap a b" |
466 by (partiality_descending, auto simp add: perm_eq_def) |
441 by transfer (auto simp add: perm_eq_def) |
467 |
442 |
468 lemma swap_commute: |
443 lemma swap_commute: |
469 "gswap a b = gswap b a" |
444 "gswap a b = gswap b a" |
470 by (partiality_descending, auto simp add: perm_eq_def) |
445 by transfer (auto simp add: perm_eq_def) |
471 |
446 |
472 lemma swap_triple: |
447 lemma swap_triple: |
473 assumes "a \<noteq> b" "c \<noteq> b" |
448 assumes "a \<noteq> b" "c \<noteq> b" |
474 shows "gswap a c + gswap b c + gswap a c = gswap a b" |
449 shows "gswap a c + gswap b c + gswap a c = gswap a b" |
475 using assms |
450 using assms |
476 by descending (auto simp add: perm_eq_def fun_eq_iff perm_add_apply) |
451 by transfer (auto simp add: perm_eq_def fun_eq_iff perm_add_apply) |
477 |
452 |
478 lemma gpermute_gswap[simp]: |
453 lemma gpermute_gswap[simp]: |
479 "b \<noteq> a \<Longrightarrow> gpermute (gswap a b) b = a" |
454 "b \<noteq> a \<Longrightarrow> gpermute (gswap a b) b = a" |
480 "a \<noteq> b \<Longrightarrow> gpermute (gswap a b) a = b" |
455 "a \<noteq> b \<Longrightarrow> gpermute (gswap a b) a = b" |
481 "c \<noteq> b \<Longrightarrow> c \<noteq> a \<Longrightarrow> gpermute (gswap a b) c = c" |
456 "c \<noteq> b \<Longrightarrow> c \<noteq> a \<Longrightarrow> gpermute (gswap a b) c = c" |
482 by (descending, auto)+ |
457 by (transfer, auto)+ |
483 |
458 |
484 lemma gperm_eq: |
459 lemma gperm_eq: |
485 "(p = q) = (\<forall>a. gpermute p a = gpermute q a)" |
460 "(p = q) = (\<forall>a. gpermute p a = gpermute q a)" |
486 by (partiality_descending) (auto simp add: perm_eq_def) |
461 by transfer (auto simp add: perm_eq_def) |
487 |
462 |
488 lemma finite_gpermute_neq: |
463 lemma finite_gpermute_neq: |
489 "finite {a. gpermute p a \<noteq> a}" |
464 "finite {a. gpermute p a \<noteq> a}" |
490 apply descending |
465 apply transfer |
491 apply (rule_tac B="fst ` set p" in finite_subset) |
466 apply (rule_tac B="fst ` set p" in finite_subset) |
492 apply auto |
467 apply auto |
493 by (metis perm_apply_outset) |
468 by (metis perm_apply_outset) |
494 |
469 |
495 end |
470 end |