CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

| Download

Try doing some basic maths questions in the Lean Theorem Prover. Functions, real numbers, equivalence relations and groups. Click on README.md and then on "Open in CoCalc with one click".

Project: Xena
Views: 18536
License: APACHE
oleanfile3.4.2, commit cbd2b6686ddb�k)inittacticrcasesdatalistdefsdataproddatasum��vexport_decloptionnonenonesomesomeexport_declboolffffttttexport_declhas_andthenandthenandthenexport_declhas_powpowpowexport_declhas_appendappendappendexport_decldecidableis_trueis_trueis_falseis_falseto_boolto_boolexport_declhas_purepurepureexport_declhas_bindbindbindexport_declhas_monad_lift_tmonad_lift!monad_liftexport_declmonad_functor_tmonad_map$monad_mapexport_declmonad_runrun'runexport_decllistmmap*mmapmmap'*mmap'mfilter*mfiltermfoldl*mfoldlexport_declnativenat_map3rb_mapmkexport_declname_mapnativerb_mapmkexport_declexpr_mapnativerb_mapmkexport_decltacticinteraction_monadfailedfailexport_decltactic_resultinteraction_monadresultexport_decltacticFtransparencyreducibleGreduciblesemireducibleGsemireducibleexport_decltacticmk_simp_attrLmk_simp_attrexport_declmonad_exceptthrowOthrowcatchOcatchexport_declmonad_except_adapteradapt_exceptTadapt_exceptexport_declmonad_state_adapteradapt_stateWadapt_stateexport_declmonad_readerreadZreadexport_declmonad_reader_adapteradapt_reader]adapt_readerexport_declis_lawful_functormap_const_eq`map_const_eqid_map`id_mapcomp_map`comp_mapexport_declis_lawful_applicativeseq_left_eqgseq_left_eqseq_right_eqgseq_right_eqpure_seq_eq_mapgpure_seq_eq_mapmap_puregmap_pureseq_puregseq_pureseq_assocgseq_assocexport_declis_lawful_monadbind_pure_comp_eq_maptbind_pure_comp_eq_mapbind_map_eq_seqtbind_map_eq_seqpure_bindtpure_bindbind_assoctbind_assocdeclderive_struct_ext_lemmannametactic~id_rhs monadto_has_bindinteraction_monadmonadtactic_stateenvironmentFget_envelistcoeoptioncoe_to_liftcoe_basetacticopt_to_tac�structure_fieldsfsdeclarationFget_decld0Fresolve_constantn	rexpr
exprconst>*listmaplevellevelparam�univ_params,prod???PFinfer_type*Fmk_local_pis_pP_aPprodcases_onN?�P*fstNsnd?	argsNC??exprto_implicit_local_const,	t?�mk_app*SFmk_local_defnamemk_string
Strxnameanonymous*x?jkl
Stryo,y?	args_xNhas_appendappendNlisthas_append?:listcons?,listnil?	args_yN~�?�mmap�f1�3znamehas_append*d0	a?A�
,HI*S�Vt?�s?itene?*reflected?�?!�?exprhas_coe��
Quote��decidable?a?b?exprhas_decidable_eq,**��	x?f4	y?f:��U,t?�t'?functormapapplicativeto_functor�to_applicative?�?�eq?,*�?S?Fmk_appl
Streqo�:�4�Ftransparencysemireduciblekl
Strho�Fmk_mappl
Strheqo��?�?�?�coe_option?:���4�����to_has_pure����bs�	bsNlistfilter_map�?id�*j��g����eq_t?jtacticpis~~���>�,*t?task?tacticrun_async?Munit??Fsolve_aux�W*�W�WFintronlistlength?	args�WS�WFintro1x?�jy?�WFcases,���_x�r_x�`�mmap'?_x?S�ie?�l*�n��_x�Wtacticreflexivity�_p�Y_a�Y[�W?��Y�*��W�?�Finstantiate_mvars**pr�R	decl_nmk_str_name
Strext�_Fadd_decldeclarationthm*I4,_x�WN�??UgbsN	rhs?exprmk_and_lst*j�l
Striffo�H�*��iff_t?j�E~�����*t?�T�V�[�^�`�a�c��args�W�jx?�jy?�r_x�r_xM?�Wtacticsplit_x���`Fsolve1�jh?���Wtacticinjection*hsN�`��subst_vars_x�W�`Frepeathas_bindand_then�W�W
Frefine
Quoteandintro_�_�'�`��_x�Whas_orelseorelsealternativeto_has_orelsetacticalternative�WFdone��_x�W���`���`��
Quote
and_impfieldNmpr�'�p_x�W�jh?�k�}_x�skip_x�W�jh?�_x����pr�R��������
Strext_iffI,*_x�W�(��*
�PInfo}#	VMR}_lambda_1VMR}_lambda_2VMR}_lambda_3VMR}_lambda_4VMR}_lambda_5VMR}_lambda_6VMR}_lambda_7VMR}_lambda_8VMR}_lambda_9VMR}_lambda_10VMR}_lambda_11VMR}_lambda_12VMR}_lambda_13VMR}_lambda_14VMR}_lambda_15VMR}_lambda_16	VMR}_lambda_17VMR}_lambda_18VMR}_lambda_19	VMR}_lambda_20VMR}_lambda_21VMR}VMC�?#	alevelparamVMC�@#	αVMC�A�#	s_fresh
��m?�Y_fresh
��l?tacticinfer_type	�a	xexprhas_decidable_eq	Anameanonymousqcharof_nate�gh�gstringemptystringstr�k�knamemk_stringtacticmk_mapp	-;�eh�g�i�k�m�@	j�eq�ge�g�i�k�k�mtacticmk_app	We�eh�g�i�k�m�j		kqv	}VMC�B5#	�X�Y_fresh
��`?�Y_fresh
��YN�Y_fresh
��XN�a	/�a	(��c			&exprmk_app_main	�?�}
�?
	�A-VMC�C!0�X��wN�zN�Y_fresh
��Cnameappend�	declarationuniv_params�?�map_main��exprconst�?�BVMC�D@a�VMC�EH�X�?�	�VMC�FV#	�X�Y_fresh
���N�Y_fresh
��QN�length_maintacticintron	P�	
I�	B�	;
�	4�E��@listmmap'_main	'-�2
9
@	
G	NVMC�G#	�X�Y_fresh
���?��N��N�F�	tacticinstantiate_mvarsVMC�H#	�X���#	
�VMC�I4#	�X�	.�	'�	 �H� 	��1interaction_monad_orelse	%,VMC�J'#	�X��#	!�	�	�9VMC�K)#	�X�J� 	#�	�	�!VMC�LX#	�X��N����	R�	
K�	D�	=	�	6�	/
�I�	#(�K�-4
;
B	
IPVMC�M#	�X�Y_fresh
���?��N�L�	��VMC�N	|#		�X�Y_fresh
���?�Y_fresh
����Y_fresh
���?�Y_fresh
��V?�Y_fresh
��T?��N���Y_fresh
��A0�ef�gf�gi�g�i�k�k�k�m�q	v
	�append_main�pis_main	'o�M�	.h
��f�gf�gi�g_�gt�gx�ge�g�i�k�k�k�k�k�k�k�mdeclarationthmtacticadd_decl	\afm
t
	
VMC�O3#	�X���Y_fresh
����R��?��?��N��?��?��N����0
������		-�a��@listmmap_main	&
exprmk_and_lst�?	
�N+

VMC�Pd#	�X��N��?��?��N����0�eq�ge�g�i�k�k�m�q	^������	%W
	�G�	-Pt�gx�ge�g�i�k�k�k�m�	�O
U
\	
	VMC�Q	&#		�X�wN�zN��?��?��N����0�Y_fresh
��?�C��@��	 
	�D�filter_map_main�N�P	
VMC�RC#	�X�Y_fresh
��R?��N����0���ex�g�i�k�m�	
=�ey�g�i�k�m�	6	���N���N�Q;	
VMC�S,#	�X�Y_fresh
��F?����0���a		Fmk_local_pis_main	&��to_implicit_local_const��
�N
�}�?
�RVMC}A#	�X~�	;environmentstructure_fields�returnopt	
4�	-�	&	���?�����?�S+	
29doc}`derive_struct_ext_lemma n` generates two extensionality lemmas based on
the equality of all non-propositional projections.

On the following:

```lean
@[ext]
structure foo (α : Type*) :=
(x y : ℕ)
(z : {z // z < x})
(k : α)
(h : x < y)
```

`derive_struct_lemma` generates:

```lean
lemma foo.ext : ∀ {α : Type u_1} (x y : foo α), x.x = y.x → x.y = y.y → x.z == y.z → x.k = y.k → x = y
lemma foo.ext_iff : ∀ {α : Type u_1} (x y : foo α), x = y ↔ x.x = y.x ∧ x.y = y.y ∧ x.z == y.z ∧ x.k = y.k
```declget_ext_subject_maina?��?�cases_on>��?*��nat?failformatformathas_to_formatz��formathas_append��to_fmtstringstringhas_to_format
StrOnly expressions of the form `_ → _ → ... → R ... e are supported: ��?exprhas_to_format>�var>*��
Str��E���������sort>*��a_aa_a_1E��������A,*��a_aa_a_1a_a_2?���������mvar>4,*��a_aa_a_1a_a_2binder_infoa_a_3?���������local_const>:4,*��a_a?a_a_1?j��V��Fhead_betat?�coe_sortboolcoe_sort_bool�is_constant>exprget_app_fn>*booldecidable_eq��>�C�const_name>�������is_pi*����>�Cnamemk_numeralhas_zerozerounsignedunsignedhas_zeroo�����is_sort*���>�C��has_oneone���has_oneo��tacticpp?exprhas_to_tactic_format*t����������
Stronly constants and Pi types are supported: ������*��a_aa_a_1��a_a_2?a_a_3?���������lam>:4,*��a_aa_a_1��a_a_2?a_a_3?jFmk_local':4,v?jFwhnf�instantiate_var,*�>b'?
�wRecFn��*a_aa_a_1?a_a_2?a_a_3?���������elet>:4,*��a_amacro_defa_a_1N���������macro>,*��
�PInfo��f	VMR��VMC���!f	a��?exprcases_on
�X����]�����	P�	q�
�n�g_c_1 �g_c_2e�g_c_3p�g_c_4r�g_c_5s�g_c_6o�g	_c_7f�g
_c_8t�g_c_9_�g_c_10�!��g
_c_11.�g_c_12�istringhas_to_formatto_fmtexprvar���8:�gd�g	u�ga�gR�g


`�gm�g	
h�g
		i�gx�gy�gl�gO�g�i�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�7�8formatcompose�<����
n�g_c_13 �g_c_14e�g_c_15p�g_c_16r�g_c_17s�g_c_18o�g	_c_19f�g
_c_20t�g_c_21_�g_c_22�!��g
_c_23.�g_c_24�i�7�8exprsort���8:�gd�g	u�ga�gR�g


`�gm�g	
h�g
		i�gx�gy�gl�gO�g�i�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�7�8�<�<����
n�g_c_25 �g_c_26e�g_c_27p�g_c_28r�g_c_29s�g	_c_30o�g
_c_31f�g_c_32t�g_c_33_�g
_c_34�!��g_c_35.�g_c_36�i�7�8�����8:�gd�g
u�g	a�gR�g

`�gm�g
h�g
	
i�g		x�gy�gl�gO�g�i�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�7�8�<�<����n�g_c_37 �g_c_38e�g_c_39p�g_c_40r�g	_c_41s�g
_c_42o�g_c_43f�g_c_44t�g
_c_45_�g_c_46�!��g_c_47.�g_c_48�i�7�8exprmvar���8:�gd�g
	u�g
	a�gR�g`�gm�g	h�g

i�g

	x�gy�gl�gO�g�i�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�7�8�<�<����n�g_c_49 �g_c_50e�g_c_51p�g	_c_52r�g
_c_53s�g_c_54o�g_c_55f�g
_c_56t�g_c_57_�g_c_58�!��g_c_59.�g_c_60�i�7�8exprlocal_const���8:�gd�g
		u�g
a�gR�g`�gm�g

h�g
i�g
	x�gy�gl�gO�g�i�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�7�8�<�<�����a	��������	����tactichead_beta��	�����{get_app_fn_main�{is_constant��_main	�����{is_pi�x	������is_sort�x	������	����o�g_c_61n�g	_c_62y�g
_c_63 �g_c_64s�g_c_65t�g
_c_66a�g_c_67d�g_c_68p�g_c_69e�g_c_70r�g_c_71�i�7�8���8:�g
u�g

i�gP�g	
	
	c�g
l�g	�i�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�7�8�<�<����
�����e4294967295finof_natnamemk_numeral���e4294967295�������v�{const_name��n�g_c_72 �g_c_73e�g_c_74p�g	_c_75r�g
_c_76s�g_c_77o�g_c_78f�g
_c_79t�g_c_80_�g_c_81�!��g_c_82.�g_c_83�i�7�8exprlam���8:�gd�g
		u�g
a�gR�g`�gm�g

h�g
i�g
	x�gy�gl�gO�g�i�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�7�8�<�<�����	�	V�	jexprinstantiate_vartacticwhnf	�	^�	c	���	h	
�	on�g_c_84 �g_c_85e�g_c_86p�g	_c_87r�g
_c_88s�g_c_89o�g_c_90f�g
_c_91t�g_c_92_�g_c_93�!��g_c_94.�g_c_95�i�7�8exprelet���8:�gd�g
		u�g
a�gR�g`�gm�g

h�g
i�g
	x�gy�gl�gO�g�i�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�7�8�<�<����n�g_c_96 �g_c_97e�g_c_98p�g_c_99r�g_c_100s�g	_c_101o�g
_c_102f�g_c_103t�g_c_104_�g
_c_105�!��g_c_106.�g_c_107�i�7�8exprmacro���8:�gd�g
u�g	a�gR�g

`�gm�g
h�g
	
i�g		x�gy�gl�gO�g�i�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�7�8�<�<����decl���w���PInfo��f	VMR��VMC��f	��declext_param_type�sum���PInfo��zVMR��VMC��decl��equations_eqn_1eq�����eqrefl����PInfo��zATTR_refl_lemma����EqnL��SEqnL��ATTRreducibility����declopt_minusleanparser����������������leanparseralternative��functormap_const��������
��parser_state���Wsuminl������tk
Str-�#���%������suminr����
�PInfo��|	VMR��_lambda_1VMR��_lambda_2VMR��_lambda_3VMR��_lambda_4VMR��VMC��|	val��VMC��|	s��-�g�i�kleanparsertk		��VMC��|	val��VMC��|	s����VMC��|	������parser_orelsedeclext_param������has_seqseq���to_has_seq��������opt_minus���������W�����	�interactivetypesbrackets�W
Str(
Str)���W��
Str→��
Str->�������
Str*����������ident
�PInfo��	VMR��_lambda_1VMR��_lambda_2VMR��_lambda_3VMR��VMC��5	����>�g-�g�i�k�k���!��g�i�k����)�g�i�k(�g�i�k��	%/�e4294967295����VMC��	����*�g�i�k��		VMC��	����leanparserident		VMC��!	�X����	����������	
declsaturate_fun�������*�namehas_decidable_eq*�����Fmk_mvarv₀?��v₁?return?��imp,*����������E?Fmk_meta_univuE�(?�����7?9*Fmk_conste?�}?Fget_arity*a�}�N?f,��}?_x�}��listiota*
�PInfo��	VMR��_lambda_1VMR��_lambda_2VMR��VMC���	�WVMC���$���}��VMC��t�	�'���e4294967295����namehas_decidable_eq	Z�e4294967295������	J�	��	D��	#=�iota_main�������	/6�};Btacticmk_meta_univ	MT�J��	]n��	`g�{impldeclequiv_type_constrnn'�W���6�hsaturate_fun,e?�<e'?��Funify,*�boolff�~�W������������namehas_to_format:������
Str and �J4��
Str are not definitionally equal types�PInfo��	VMR�VMC���	�X����	���	� �g_c_1a�g_c_2�i�k�k	_c_3n�g
_c_4d�g_c_5e�g_c_6o�g
_c_7t�g_c_8i�g_c_9l�g_c_10y�g_c_11s�gp�gu�gq�g


f�g

r�g	�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�7�8��8
	�k�k�k�7�8�<�<��8�i�7�8�<�<����tacticunify��
�declextensional_attribute_mainuser_attributename_mapM��M��M���nuser_attributemk�c�ml��o
Strlemmas usable by `ext` tactic�declprio�}persistent���6n_x�}b���m�W�get_param�c�m
Quote�m
�nRecFn�4_p�m_a�m[���l�+�m�6*�����lboolcases_on����6,[�f�k��l�6*snd_fst�fsnd_snd�k[�j�/�k�6*snd_snd_fstsnd_snd_snd�j�9�We7�W����is_some+����>derive_struct_ext_lemma���C��n��j��*Uget_ext_subjects_a�h���8���6*���9�`�u�Wequiv_type_constr:*_x�W	lhas_unionunion�has_union����,*,has_sdiffsdifflisthas_sdiff��C�iprodfstlistfilter�il�i��prodsnd*�a�i�������4�set�c�m
Quote�m���prodmk���l>���f�k������j*��i����}���listempty������>�����n�*�n�Npartition_map��summap����flip��optionget_or_else*�-��9�(�Wunitstar*�decl�xuser_attribute_cache_cfgmk�cls�j�c��jl�|�j��
Quote�m��*_p�m_a�m���^�m�j*�����l����l�b*snd_fst�fsnd_snd�k���`�k�b*snd_snd_fstsnd_snd_snd�j�b�(�j�����listmonad�i���ra�i��,�#�%�r�F**attrs�X�(�c3rb_mapof_listnamehas_lt��nameltdecidable_rel,*�join�i*�na�mprodhas_reflect���o��boolhas_reflect*�l�o�l���f�o�flistreflect���o��sumhas_reflect���o��optionhas_reflect�onamereflect*
Quote*���o����
Quote*
Quote��
Quote��*
Quote��*�k�o�k���o����
Quote*�j�o�j���i�o�i������
Quote
Quote*
Quote�i*
Quote
Quote�j*
Quote�f
Quote�k*
Quote��
Quote�l*�������f�m���f�����f����ext_param���list_of������f��ls�f��c�m�c���c�&�(!�&�(leanparserhas_coe'�c�get_cache�c�m��m�c���m���A��,���n3rb_mapto_list*�PInfo��	VMR�_lambda_1VMR�_lambda_2VMR�_lambda_3VMR�_lambda_4VMR�_lambda_5VMR�_lambda_6VMR�_lambda_7VMR�_lambda_8VMR�_lambda_9VMR�_lambda_10VMR�_lambda_11VMR�VMC���	�WVMC���	c�i
VMC���	�J�i�Y_fresh��)
��VMC�����X�(���'�}�&��muser_attributeget_param	�	�	�	���optionis_some_main�x	
"
}	#���	',�a1	27��<	=��empty_main�x	CY��get_or_else_mainflip_c_1summap_main�Apartition_map_main^������	k����filter_main�������diff_main���union�;��muser_attributeset����
�VMC���	_x�|�Y_fresh��T��VMC���	��VMC��$�1�X�\��m��	���������join_mainVMC����X�[�������	���m�j�gof_list_mainVMC���	������	
VMC���	����VMC��.�	�X�������}������	(�user_attributeget_cache��of_tactic'	!�gto_list&VMC���	�et�gx�ge�g�i�k�k�k�mc�gi�gt�gc�ga�gt�g �g`�gt�gx�ge�g`�g �gy�gb�g �ge�gl�gb�ga�gs�gu�g �gs�ga�gm�gm�ge�gl�g�i�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�����l���k�f�j�i�{_main���phas_reflect�u_main���������������xhas_reflect�����vhas_reflect�����rhas_reflect����decl��n��PInfo��	VMR�VMC��	�doc�Tag lemmas of the form:

```lean
@[ext]
lemma my_collection.ext (a b : my_collection)
  (h : ∀ x, a.lookup x = b.lookup y) :
  a = b := ...
```

The attribute indexes extensionality lemma using the type of the
objects (i.e. `my_collection`) which it gets from the statement of
the lemma.  In some cases, the same lemma can be used to state the
extensionality of multiple types that are definitionally equivalent.

```lean
attribute [ext [(→),thunk,stream]] funext
```

Those parameters are cumulative. The following are equivalent:

```lean
attribute [ext [(→),thunk]] funext
attribute [ext [stream]] funext
```
and
```lean
attribute [ext [(→),thunk,stream]] funext
```

One removes type names from the list for one lemma with:
```lean
attribute [ext [-stream,-thunk]] funext
 ```

Also, the following:

```lean
@[ext]
lemma my_collection.ext (a b : my_collection)
  (h : ∀ x, a.lookup x = b.lookup y) :
  a = b := ...
```

is equivalent to

```lean
@[ext *]
lemma my_collection.ext (a b : my_collection)
  (h : ∀ x, a.lookup x = b.lookup y) :
  a = b := ...
```

This allows us specify type synonyms along with the type
that referred to in the lemma statement.

```lean
@[ext [*,my_type_synonym]]
lemma my_collection.ext (a b : my_collection)
  (h : ∀ x, a.lookup x = b.lookup y) :
  a = b := ...
```

Attribute `ext` can be applied to a structure to generate its extensionality lemma:

```lean
@[ext]
structure foo (α : Type*) :=
(x y : ℕ)
(z : {z // z < x})
(k : α)
(h : x < y)
```

will generate:

```lean
@[ext] lemma foo.ext : ∀ {α : Type u_1} (x y : foo α), x.x = y.x → x.y = y.y → x.z == y.z → x.k = y.k → x = y
lemma foo.ext_iff : ∀ {α : Type u_1} (x y : foo α), x = y ↔ x.x = y.x ∧ x.y = y.y ∧ x.z == y.z ∧ x.k = y.k
```ATTRuser_attribute���USR_ATTR�ATTRext��arrayext�:���<��ATTR�������������l
Strarrayo�n��ATTR����propext�NATTR���������������unsignedof_nat'��}nathas_oneo�n��ATTR����prodext�NATTR�������������l
Strprodo�n��ATTR����funext�:������������X���}nathas_zeroo�n����l
Strthunko���<��i��Q�s�Q����g�s�g����^l
Strpropexto��ATTR��������������t��z�n��decluliftextu₁u₂α��Xulift��*Y��,w�4��down	4,��*�	��:4,����������������uliftcases_on	:������������*��4����g,:4��:��������up	�*����g���������������4��*����������:,:��g��������*id����������������,�����F���F���4����:,eqmpr����������������eqrec�F�_a�F�������d���dg�:���*������4*eqrefl����***�PInfo���
ATTR�������:���<����zl
Strfunexto����������t�*��ATTR�������������l
Strulifto�n��declpliftextP�aplift*b�A,��A4,*������B���Cpliftcases_on4���D��A:*,,��4�K:���M��A���up�,*,��:��U�Y�PInfo���
ATTR�������:���<�,����:�s�:�3ATTR�������������l
Strplifto�n��decltactictry_intros_main����ext_patt�z���zlistcases_ontacticrcases_patt���z�{*�{functormap_const_rev��z�W��tryN��intros��~a_hd�~a_tl�~��S�z���targete?�J*�>tgt?���{���z
��rintro��~4��
�|RecFn��,�(�z��,�PInfo���	VMR��VMC��F�	�'���zlistcases_onFintros�try	tactictarget	��!	"?�y�x	'-=��rintro	38��=Ddecl��try_intros�|���PInfo��	VMR�VMC��	��decl��ext1xs�zcfgopt_param��apply_cfgFapply_cfgmk�>Fnew_goalsnon_dep_first>>>>�{��z�����7�zj����subject�c�z�5extensional_attributem�c�_�z��������!��$��find*,rule��applyc*:���kattributeget_instances�tlslistany_of�W*n����F������
Strno applicable extensionality rule found for �J,��_x�W��try_intros��PInfo��	VMR�_lambda_1VMR�_lambda_2VMR�_lambda_3VMR�VMC��	�X�Y_fresh��n�c�Y_fresh��l�Y_fresh��e��nativerb_mapfind��		FapplycVMC��%��&���*VMC�$�	�X�&���et�gx�ge�g�i�k�k�k�mattributeget_instances	�listany_of_mainVMC��)�	�X�����z�	��
	�#���	��i�7�8��8 �gr�go�gf�g �gd�gn�gu�go�gf�g �ge�gl�gu�gr�g �gy�gt�gi�gl�ga�gn�go�gi�gs�gn�ge�gt�gx�ge�g �ge�gl�gb�ga�gc�gi�gl�gp�gp�ga�g �go�gn�g�i�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�k�7�8�<�<����������	�����	�!decl��ext_main���z���}�6���z���	optioncases_on�}���	�6*�9��focus1�W�z�W��ext1,��ys�z���W
�RecFn�1*�����monad�}�}natpred�a_1�}���}*��
�}Annotinnaccessible
�pAnnot�;natdecidable_eq*�4�6�9��9���4���6�z���&��},�PInfo�1�)	VMR�1_lambda_1VMR�1_lambda_2VMR�1VMC�>�)	�X�Y_fresh��T�z�	�<pred��map�1��VMC�?�)	�X�Y_fresh��]�}�B�z�	�C�D�1��VMC�1�)	�'���	���z	�>Ffocus1natdecidable_eq	�?�H�9decl��ext��1�PInfo�K�)	VMR�KVMC�K�)	�1decl��interactiveext1xs��parse�z�o�z���~�o�~��rcases_patthas_reflect*
Quote�~*��ext_parse�6�N�]�9���W�z�*���C�PInfo�M�8	VMR�MVMC�M�8	���N�]�	doc�M`ext1 id` selects and apply one extensionality lemma (with attribute
`ext`), using `id`, if provided, to name a local constant
introduced by the lemma. If `id` is omitted, the local constant is
named automatically, as per `intro`.decl��interactiveext���Q�o�z�V
Quote�~*�\���P�	�o�	���}�o�}natreflect*
Quote�}*optional�����}has_seq_rightseq_right���to_has_seq_right�����W�}��
Str:��small_nat�6���Q�o�z�V
Quote�~*�\���m�o�	�r
Quote�}*��������6,�
�����6*�9��repeat1�`������C���}�9��iterate_range�[*��a_hd�~a_tl���9tacticext��,*4�PInfo�T�V	VMR�T_lambda_1VMR�TVMC�b�V	���	VMC�T�V	�'����������		�b�repeat1�b�iterate_range_main�1doc�T- `ext` applies as many extensionality lemmas as possible;
- `ext ids`, with `ids` a list of identifiers, finds extentionality and applies them
  until it runs out of identifiers in `ids` to name the local constants.

When trying to prove:

```lean
α β : Type,
f g : α → set β
⊢ f = g
```

applying `ext x y` yields:

```lean
α β : Type,
f g : α → set β,
x : α,
y : β
⊢ y ∈ f x ↔ y ∈ f x
```

by applying functional extensionality and set extensionality.

A maximum depth can be provided with `ext x y z : 3`.EndFile