aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcorbinea2003-02-24 17:12:57 +0000
committercorbinea2003-02-24 17:12:57 +0000
commitb496630ec937dbf2d823d76c53cf6ab81b1544a9 (patch)
tree958784db6939aef7b8a137a910abd42778fdd4ac
parent3ae01fb7081658f9c2efaa24f4a7f69925dd6e95 (diff)
Bringing Linear back to life (Still somewhat buggy).
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@3699 85f007b7-540e-0410-9357-904b9bb8a0f7
-rw-r--r--.depend210
-rw-r--r--.depend.camlp42
-rw-r--r--Makefile19
-rwxr-xr-xcontrib/linear/ccidpc.ml4371
-rwxr-xr-xcontrib/linear/dpc.ml464
-rw-r--r--contrib/linear/dpctypes.ml60
-rwxr-xr-xcontrib/linear/dpctypes.mli59
-rwxr-xr-xcontrib/linear/general.ml41
-rwxr-xr-xcontrib/linear/general.mli16
-rwxr-xr-xcontrib/linear/graph.ml70
-rwxr-xr-xcontrib/linear/graph.mli12
-rwxr-xr-xcontrib/linear/kwc.ml233
-rwxr-xr-xcontrib/linear/lk_proofs.ml730
-rwxr-xr-xcontrib/linear/prove.ml80
-rwxr-xr-xcontrib/linear/prove.mli19
-rwxr-xr-xcontrib/linear/subst.ml150
-rwxr-xr-xcontrib/linear/subst.mli21
-rwxr-xr-xcontrib/linear/unif.ml311
-rwxr-xr-xcontrib/linear/unif.mli27
19 files changed, 2421 insertions, 74 deletions
diff --git a/.depend b/.depend
index 5d45780062..a4390d7ed2 100644
--- a/.depend
+++ b/.depend
@@ -40,10 +40,10 @@ kernel/indtypes.cmi: kernel/declarations.cmi kernel/entries.cmi \
kernel/univ.cmi
kernel/inductive.cmi: kernel/declarations.cmi kernel/environ.cmi \
kernel/names.cmi kernel/term.cmi kernel/univ.cmi
-kernel/mod_typing.cmi: kernel/declarations.cmi kernel/entries.cmi \
- kernel/environ.cmi
kernel/modops.cmi: kernel/declarations.cmi kernel/entries.cmi \
kernel/environ.cmi kernel/names.cmi kernel/univ.cmi lib/util.cmi
+kernel/mod_typing.cmi: kernel/declarations.cmi kernel/entries.cmi \
+ kernel/environ.cmi
kernel/names.cmi: lib/pp.cmi lib/predicate.cmi
kernel/reduction.cmi: kernel/environ.cmi kernel/sign.cmi kernel/term.cmi \
kernel/univ.cmi
@@ -63,9 +63,6 @@ kernel/typeops.cmi: kernel/entries.cmi kernel/environ.cmi kernel/names.cmi \
kernel/univ.cmi: kernel/names.cmi lib/pp.cmi
lib/bignat.cmi: lib/pp.cmi
lib/pp.cmi: lib/pp_control.cmi
-lib/rtree.cmi: lib/pp.cmi
-lib/system.cmi: lib/pp.cmi
-lib/util.cmi: lib/pp.cmi
library/declare.cmi: kernel/cooking.cmi library/decl_kinds.cmo \
kernel/declarations.cmi library/dischargedhypsmap.cmi kernel/entries.cmi \
kernel/indtypes.cmi library/libnames.cmi library/libobject.cmi \
@@ -94,7 +91,9 @@ library/library.cmi: library/libnames.cmi library/libobject.cmi \
library/nameops.cmi: kernel/names.cmi lib/pp.cmi
library/nametab.cmi: library/libnames.cmi kernel/names.cmi lib/pp.cmi \
kernel/sign.cmi lib/util.cmi
-library/summary.cmi: library/libnames.cmi kernel/names.cmi
+lib/rtree.cmi: lib/pp.cmi
+lib/system.cmi: lib/pp.cmi
+lib/util.cmi: lib/pp.cmi
parsing/ast.cmi: parsing/coqast.cmi lib/dyn.cmi interp/genarg.cmi \
library/libnames.cmi kernel/names.cmi lib/pp.cmi interp/topconstr.cmi \
lib/util.cmi
@@ -308,11 +307,11 @@ toplevel/recordobj.cmi: library/libnames.cmi proofs/tacexpr.cmo
toplevel/searchisos.cmi: library/libobject.cmi kernel/names.cmi \
kernel/term.cmi
toplevel/toplevel.cmi: parsing/pcoq.cmi lib/pp.cmi
-toplevel/vernac.cmi: parsing/pcoq.cmi lib/util.cmi toplevel/vernacexpr.cmo
toplevel/vernacentries.cmi: kernel/environ.cmi pretyping/evd.cmi \
library/libnames.cmi kernel/names.cmi kernel/term.cmi \
interp/topconstr.cmi toplevel/vernacexpr.cmo toplevel/vernacinterp.cmi
toplevel/vernacinterp.cmi: proofs/tacexpr.cmo
+toplevel/vernac.cmi: parsing/pcoq.cmi lib/util.cmi toplevel/vernacexpr.cmo
translate/ppconstrnew.cmi: parsing/coqast.cmi kernel/environ.cmi \
parsing/extend.cmi library/libnames.cmi kernel/names.cmi parsing/pcoq.cmi \
lib/pp.cmi pretyping/rawterm.cmi proofs/tacexpr.cmo kernel/term.cmi \
@@ -329,11 +328,11 @@ contrib/cc/ccalgo.cmi: kernel/names.cmi kernel/term.cmi
contrib/cc/ccproof.cmi: contrib/cc/ccalgo.cmi kernel/names.cmi
contrib/correctness/past.cmi: kernel/names.cmi contrib/correctness/ptype.cmi \
kernel/term.cmi interp/topconstr.cmi lib/util.cmi
-contrib/correctness/pcic.cmi: contrib/correctness/past.cmi \
- pretyping/rawterm.cmi
contrib/correctness/pcicenv.cmi: kernel/names.cmi \
contrib/correctness/penv.cmi contrib/correctness/prename.cmi \
kernel/sign.cmi kernel/term.cmi
+contrib/correctness/pcic.cmi: contrib/correctness/past.cmi \
+ pretyping/rawterm.cmi
contrib/correctness/pdb.cmi: kernel/names.cmi contrib/correctness/past.cmi \
contrib/correctness/ptype.cmi
contrib/correctness/peffect.cmi: kernel/names.cmi lib/pp.cmi
@@ -420,6 +419,11 @@ contrib/jprover/jall.cmi: contrib/jprover/jlogic.cmi \
contrib/jprover/jterm.cmi contrib/jprover/opname.cmi
contrib/jprover/jlogic.cmi: contrib/jprover/jterm.cmi
contrib/jprover/jterm.cmi: contrib/jprover/opname.cmi
+contrib/linear/dpctypes.cmi: kernel/names.cmi kernel/term.cmi
+contrib/linear/prove.cmi: contrib/linear/dpctypes.cmi
+contrib/linear/subst.cmi: contrib/linear/dpctypes.cmi kernel/names.cmi
+contrib/linear/unif.cmi: contrib/linear/dpctypes.cmi \
+ contrib/linear/general.cmi
contrib/xml/doubleTypeInference.cmi: contrib/xml/acic.cmo kernel/environ.cmi \
pretyping/evd.cmi kernel/term.cmi
contrib/xml/xmlcommand.cmi: library/libnames.cmi
@@ -443,6 +447,12 @@ dev/top_printers.cmx: parsing/ast.cmx toplevel/cerrors.cmx proofs/clenv.cmx \
pretyping/termops.cmx kernel/univ.cmx
doc/parse.cmo: parsing/ast.cmi
doc/parse.cmx: parsing/ast.cmx
+ide/coqide.cmo: ide/coq.cmi ide/find_phrase.cmo ide/highlight.cmo \
+ ide/ideutils.cmo proofs/pfedit.cmi lib/pp_control.cmi ide/preferences.cmo \
+ lib/util.cmi toplevel/vernacexpr.cmo
+ide/coqide.cmx: ide/coq.cmx ide/find_phrase.cmx ide/highlight.cmx \
+ ide/ideutils.cmx proofs/pfedit.cmx lib/pp_control.cmx ide/preferences.cmx \
+ lib/util.cmx toplevel/vernacexpr.cmx
ide/coq.cmo: toplevel/cerrors.cmi config/coq_config.cmi toplevel/coqtop.cmi \
kernel/environ.cmi pretyping/evarutil.cmi pretyping/evd.cmi \
tactics/hipattern.cmi ide/ideutils.cmo library/lib.cmi kernel/names.cmi \
@@ -459,12 +469,6 @@ ide/coq.cmx: toplevel/cerrors.cmx config/coq_config.cmx toplevel/coqtop.cmx \
proofs/refiner.cmx library/states.cmx proofs/tacmach.cmx kernel/term.cmx \
lib/util.cmx toplevel/vernac.cmx toplevel/vernacentries.cmx \
toplevel/vernacexpr.cmx ide/coq.cmi
-ide/coqide.cmo: ide/coq.cmi ide/find_phrase.cmo ide/highlight.cmo \
- ide/ideutils.cmo proofs/pfedit.cmi lib/pp_control.cmi lib/util.cmi \
- toplevel/vernacexpr.cmo
-ide/coqide.cmx: ide/coq.cmx ide/find_phrase.cmx ide/highlight.cmx \
- ide/ideutils.cmx proofs/pfedit.cmx lib/pp_control.cmx lib/util.cmx \
- toplevel/vernacexpr.cmx
ide/find_phrase.cmo: ide/ideutils.cmo
ide/find_phrase.cmx: ide/ideutils.cmx
ide/highlight.cmo: ide/ideutils.cmo
@@ -595,6 +599,12 @@ kernel/inductive.cmo: kernel/declarations.cmi kernel/environ.cmi \
kernel/inductive.cmx: kernel/declarations.cmx kernel/environ.cmx \
kernel/names.cmx kernel/reduction.cmx kernel/sign.cmx kernel/term.cmx \
kernel/type_errors.cmx kernel/univ.cmx lib/util.cmx kernel/inductive.cmi
+kernel/modops.cmo: kernel/declarations.cmi kernel/entries.cmi \
+ kernel/environ.cmi kernel/names.cmi lib/pp.cmi kernel/term.cmi \
+ kernel/univ.cmi lib/util.cmi kernel/modops.cmi
+kernel/modops.cmx: kernel/declarations.cmx kernel/entries.cmx \
+ kernel/environ.cmx kernel/names.cmx lib/pp.cmx kernel/term.cmx \
+ kernel/univ.cmx lib/util.cmx kernel/modops.cmi
kernel/mod_typing.cmo: kernel/declarations.cmi kernel/entries.cmi \
kernel/environ.cmi kernel/modops.cmi kernel/names.cmi \
kernel/reduction.cmi kernel/subtyping.cmi kernel/term_typing.cmi \
@@ -603,12 +613,6 @@ kernel/mod_typing.cmx: kernel/declarations.cmx kernel/entries.cmx \
kernel/environ.cmx kernel/modops.cmx kernel/names.cmx \
kernel/reduction.cmx kernel/subtyping.cmx kernel/term_typing.cmx \
kernel/typeops.cmx kernel/univ.cmx lib/util.cmx kernel/mod_typing.cmi
-kernel/modops.cmo: kernel/declarations.cmi kernel/entries.cmi \
- kernel/environ.cmi kernel/names.cmi lib/pp.cmi kernel/term.cmi \
- kernel/univ.cmi lib/util.cmi kernel/modops.cmi
-kernel/modops.cmx: kernel/declarations.cmx kernel/entries.cmx \
- kernel/environ.cmx kernel/names.cmx lib/pp.cmx kernel/term.cmx \
- kernel/univ.cmx lib/util.cmx kernel/modops.cmi
kernel/names.cmo: lib/hashcons.cmi lib/pp.cmi lib/predicate.cmi lib/util.cmi \
kernel/names.cmi
kernel/names.cmx: lib/hashcons.cmx lib/pp.cmx lib/predicate.cmx lib/util.cmx \
@@ -691,34 +695,24 @@ lib/edit.cmo: lib/bstack.cmi lib/pp.cmi lib/util.cmi lib/edit.cmi
lib/edit.cmx: lib/bstack.cmx lib/pp.cmx lib/util.cmx lib/edit.cmi
lib/explore.cmo: lib/explore.cmi
lib/explore.cmx: lib/explore.cmi
-lib/gmap.cmo: lib/gmap.cmi
-lib/gmap.cmx: lib/gmap.cmi
lib/gmapl.cmo: lib/gmap.cmi lib/util.cmi lib/gmapl.cmi
lib/gmapl.cmx: lib/gmap.cmx lib/util.cmx lib/gmapl.cmi
+lib/gmap.cmo: lib/gmap.cmi
+lib/gmap.cmx: lib/gmap.cmi
lib/gset.cmo: lib/gset.cmi
lib/gset.cmx: lib/gset.cmi
lib/hashcons.cmo: lib/hashcons.cmi
lib/hashcons.cmx: lib/hashcons.cmi
lib/options.cmo: lib/util.cmi lib/options.cmi
lib/options.cmx: lib/util.cmx lib/options.cmi
-lib/pp.cmo: lib/pp_control.cmi lib/pp.cmi
-lib/pp.cmx: lib/pp_control.cmx lib/pp.cmi
lib/pp_control.cmo: lib/pp_control.cmi
lib/pp_control.cmx: lib/pp_control.cmi
+lib/pp.cmo: lib/pp_control.cmi lib/pp.cmi
+lib/pp.cmx: lib/pp_control.cmx lib/pp.cmi
lib/predicate.cmo: lib/predicate.cmi
lib/predicate.cmx: lib/predicate.cmi
lib/profile.cmo: lib/profile.cmi
lib/profile.cmx: lib/profile.cmi
-lib/rtree.cmo: lib/pp.cmi lib/util.cmi lib/rtree.cmi
-lib/rtree.cmx: lib/pp.cmx lib/util.cmx lib/rtree.cmi
-lib/stamps.cmo: lib/stamps.cmi
-lib/stamps.cmx: lib/stamps.cmi
-lib/system.cmo: config/coq_config.cmi lib/pp.cmi lib/util.cmi lib/system.cmi
-lib/system.cmx: config/coq_config.cmx lib/pp.cmx lib/util.cmx lib/system.cmi
-lib/tlm.cmo: lib/gmap.cmi lib/gset.cmi lib/tlm.cmi
-lib/tlm.cmx: lib/gmap.cmx lib/gset.cmx lib/tlm.cmi
-lib/util.cmo: lib/pp.cmi lib/util.cmi
-lib/util.cmx: lib/pp.cmx lib/util.cmi
library/declare.cmo: library/decl_kinds.cmo kernel/declarations.cmi \
library/dischargedhypsmap.cmi kernel/entries.cmi kernel/environ.cmi \
library/global.cmi library/impargs.cmi kernel/indtypes.cmi \
@@ -823,6 +817,16 @@ library/states.cmx: library/lib.cmx library/library.cmx library/summary.cmx \
lib/system.cmx library/states.cmi
library/summary.cmo: lib/dyn.cmi lib/pp.cmi lib/util.cmi library/summary.cmi
library/summary.cmx: lib/dyn.cmx lib/pp.cmx lib/util.cmx library/summary.cmi
+lib/rtree.cmo: lib/pp.cmi lib/util.cmi lib/rtree.cmi
+lib/rtree.cmx: lib/pp.cmx lib/util.cmx lib/rtree.cmi
+lib/stamps.cmo: lib/stamps.cmi
+lib/stamps.cmx: lib/stamps.cmi
+lib/system.cmo: config/coq_config.cmi lib/pp.cmi lib/util.cmi lib/system.cmi
+lib/system.cmx: config/coq_config.cmx lib/pp.cmx lib/util.cmx lib/system.cmi
+lib/tlm.cmo: lib/gmap.cmi lib/gset.cmi lib/tlm.cmi
+lib/tlm.cmx: lib/gmap.cmx lib/gset.cmx lib/tlm.cmi
+lib/util.cmo: lib/pp.cmi lib/util.cmi
+lib/util.cmx: lib/pp.cmx lib/util.cmi
parsing/argextend.cmo: parsing/ast.cmi interp/genarg.cmi parsing/pcoq.cmi \
parsing/q_coqast.cmo parsing/q_util.cmi lib/util.cmi \
toplevel/vernacexpr.cmo
@@ -1831,10 +1835,10 @@ tactics/wcclausenv.cmx: proofs/clenv.cmx kernel/environ.cmx \
pretyping/reductionops.cmx proofs/refiner.cmx kernel/sign.cmx \
proofs/tacmach.cmx kernel/term.cmx pretyping/termops.cmx lib/util.cmx \
tactics/wcclausenv.cmi
-tools/coq_vo2xml.cmo: config/coq_config.cmi toplevel/usage.cmi
-tools/coq_vo2xml.cmx: config/coq_config.cmx toplevel/usage.cmx
tools/coqdep.cmo: config/coq_config.cmi tools/coqdep_lexer.cmo
tools/coqdep.cmx: config/coq_config.cmx tools/coqdep_lexer.cmx
+tools/coq_vo2xml.cmo: config/coq_config.cmi toplevel/usage.cmi
+tools/coq_vo2xml.cmx: config/coq_config.cmx toplevel/usage.cmx
tools/gallina.cmo: tools/gallina_lexer.cmo
tools/gallina.cmx: tools/gallina_lexer.cmx
toplevel/cerrors.cmo: parsing/ast.cmi pretyping/cases.cmi toplevel/himsg.cmi \
@@ -2037,16 +2041,6 @@ toplevel/toplevel.cmx: toplevel/cerrors.cmx library/lib.cmx \
toplevel/vernac.cmx toplevel/vernacexpr.cmx toplevel/toplevel.cmi
toplevel/usage.cmo: config/coq_config.cmi toplevel/usage.cmi
toplevel/usage.cmx: config/coq_config.cmx toplevel/usage.cmi
-toplevel/vernac.cmo: parsing/coqast.cmi parsing/lexer.cmi library/lib.cmi \
- library/library.cmi kernel/names.cmi lib/options.cmi parsing/pcoq.cmi \
- proofs/pfedit.cmi lib/pp.cmi translate/ppvernacnew.cmi library/states.cmi \
- lib/system.cmi lib/util.cmi toplevel/vernacentries.cmi \
- toplevel/vernacexpr.cmo toplevel/vernacinterp.cmi toplevel/vernac.cmi
-toplevel/vernac.cmx: parsing/coqast.cmx parsing/lexer.cmx library/lib.cmx \
- library/library.cmx kernel/names.cmx lib/options.cmx parsing/pcoq.cmx \
- proofs/pfedit.cmx lib/pp.cmx translate/ppvernacnew.cmx library/states.cmx \
- lib/system.cmx lib/util.cmx toplevel/vernacentries.cmx \
- toplevel/vernacexpr.cmx toplevel/vernacinterp.cmx toplevel/vernac.cmi
toplevel/vernacentries.cmo: tactics/auto.cmi toplevel/class.cmi \
pretyping/classops.cmi toplevel/command.cmi interp/constrextern.cmi \
interp/constrintern.cmi library/decl_kinds.cmo library/declaremods.cmi \
@@ -2107,6 +2101,16 @@ toplevel/vernacinterp.cmx: parsing/ast.cmx parsing/coqast.cmx \
kernel/names.cmx lib/options.cmx lib/pp.cmx proofs/proof_type.cmx \
proofs/tacexpr.cmx tactics/tacinterp.cmx lib/util.cmx \
toplevel/vernacexpr.cmx toplevel/vernacinterp.cmi
+toplevel/vernac.cmo: parsing/coqast.cmi parsing/lexer.cmi library/lib.cmi \
+ library/library.cmi kernel/names.cmi lib/options.cmi parsing/pcoq.cmi \
+ proofs/pfedit.cmi lib/pp.cmi translate/ppvernacnew.cmi library/states.cmi \
+ lib/system.cmi lib/util.cmi toplevel/vernacentries.cmi \
+ toplevel/vernacexpr.cmo toplevel/vernacinterp.cmi toplevel/vernac.cmi
+toplevel/vernac.cmx: parsing/coqast.cmx parsing/lexer.cmx library/lib.cmx \
+ library/library.cmx kernel/names.cmx lib/options.cmx parsing/pcoq.cmx \
+ proofs/pfedit.cmx lib/pp.cmx translate/ppvernacnew.cmx library/states.cmx \
+ lib/system.cmx lib/util.cmx toplevel/vernacentries.cmx \
+ toplevel/vernacexpr.cmx toplevel/vernacinterp.cmx toplevel/vernac.cmi
translate/ppconstrnew.cmo: parsing/ast.cmi lib/bignat.cmi \
interp/constrextern.cmi interp/constrintern.cmi parsing/coqast.cmi \
lib/dyn.cmi parsing/esyntax.cmi pretyping/evd.cmi interp/genarg.cmi \
@@ -2169,6 +2173,18 @@ contrib/cc/cctac.cmx: contrib/cc/ccalgo.cmx contrib/cc/ccproof.cmx \
lib/pp.cmx parsing/pptactic.cmx proofs/proof_type.cmx proofs/refiner.cmx \
tactics/tacinterp.cmx proofs/tacmach.cmx tactics/tacticals.cmx \
tactics/tactics.cmx kernel/term.cmx lib/util.cmx
+contrib/correctness/pcicenv.cmo: library/global.cmi kernel/names.cmi \
+ contrib/correctness/past.cmi contrib/correctness/penv.cmi \
+ contrib/correctness/pmisc.cmi contrib/correctness/pmonad.cmi \
+ contrib/correctness/prename.cmi contrib/correctness/ptype.cmi \
+ contrib/correctness/putil.cmi kernel/sign.cmi kernel/term.cmi \
+ kernel/univ.cmi contrib/correctness/pcicenv.cmi
+contrib/correctness/pcicenv.cmx: library/global.cmx kernel/names.cmx \
+ contrib/correctness/past.cmi contrib/correctness/penv.cmx \
+ contrib/correctness/pmisc.cmx contrib/correctness/pmonad.cmx \
+ contrib/correctness/prename.cmx contrib/correctness/ptype.cmi \
+ contrib/correctness/putil.cmx kernel/sign.cmx kernel/term.cmx \
+ kernel/univ.cmx contrib/correctness/pcicenv.cmi
contrib/correctness/pcic.cmo: kernel/declarations.cmi library/declare.cmi \
pretyping/detyping.cmi kernel/entries.cmi library/global.cmi \
kernel/indtypes.cmi library/libnames.cmi library/nameops.cmi \
@@ -2185,18 +2201,6 @@ contrib/correctness/pcic.cmx: kernel/declarations.cmx library/declare.cmx \
kernel/sign.cmx kernel/term.cmx pretyping/termops.cmx \
interp/topconstr.cmx kernel/typeops.cmx lib/util.cmx \
toplevel/vernacexpr.cmx contrib/correctness/pcic.cmi
-contrib/correctness/pcicenv.cmo: library/global.cmi kernel/names.cmi \
- contrib/correctness/past.cmi contrib/correctness/penv.cmi \
- contrib/correctness/pmisc.cmi contrib/correctness/pmonad.cmi \
- contrib/correctness/prename.cmi contrib/correctness/ptype.cmi \
- contrib/correctness/putil.cmi kernel/sign.cmi kernel/term.cmi \
- kernel/univ.cmi contrib/correctness/pcicenv.cmi
-contrib/correctness/pcicenv.cmx: library/global.cmx kernel/names.cmx \
- contrib/correctness/past.cmi contrib/correctness/penv.cmx \
- contrib/correctness/pmisc.cmx contrib/correctness/pmonad.cmx \
- contrib/correctness/prename.cmx contrib/correctness/ptype.cmi \
- contrib/correctness/putil.cmx kernel/sign.cmx kernel/term.cmx \
- kernel/univ.cmx contrib/correctness/pcicenv.cmi
contrib/correctness/pdb.cmo: library/declare.cmi library/global.cmi \
kernel/names.cmi library/nametab.cmi contrib/correctness/past.cmi \
contrib/correctness/peffect.cmi contrib/correctness/penv.cmi \
@@ -2737,6 +2741,14 @@ contrib/interface/pbp.cmx: interp/coqlib.cmx kernel/environ.cmx \
tactics/tacinterp.cmx proofs/tacmach.cmx tactics/tacticals.cmx \
tactics/tactics.cmx kernel/term.cmx interp/topconstr.cmx \
pretyping/typing.cmx lib/util.cmx contrib/interface/pbp.cmi
+contrib/interface/showproof_ct.cmo: contrib/interface/ascent.cmi \
+ parsing/esyntax.cmi library/global.cmi toplevel/metasyntax.cmi lib/pp.cmi \
+ parsing/printer.cmi contrib/interface/translate.cmi \
+ contrib/interface/vtp.cmi contrib/interface/xlate.cmi
+contrib/interface/showproof_ct.cmx: contrib/interface/ascent.cmi \
+ parsing/esyntax.cmx library/global.cmx toplevel/metasyntax.cmx lib/pp.cmx \
+ parsing/printer.cmx contrib/interface/translate.cmx \
+ contrib/interface/vtp.cmx contrib/interface/xlate.cmx
contrib/interface/showproof.cmo: proofs/clenv.cmi interp/constrintern.cmi \
parsing/coqast.cmi kernel/declarations.cmi kernel/environ.cmi \
pretyping/evd.cmi interp/genarg.cmi library/global.cmi \
@@ -2761,14 +2773,6 @@ contrib/interface/showproof.cmx: proofs/clenv.cmx interp/constrintern.cmx \
pretyping/termops.cmx contrib/interface/translate.cmx \
pretyping/typing.cmx lib/util.cmx toplevel/vernacinterp.cmx \
contrib/interface/showproof.cmi
-contrib/interface/showproof_ct.cmo: contrib/interface/ascent.cmi \
- parsing/esyntax.cmi library/global.cmi toplevel/metasyntax.cmi lib/pp.cmi \
- parsing/printer.cmi contrib/interface/translate.cmi \
- contrib/interface/vtp.cmi contrib/interface/xlate.cmi
-contrib/interface/showproof_ct.cmx: contrib/interface/ascent.cmi \
- parsing/esyntax.cmx library/global.cmx toplevel/metasyntax.cmx lib/pp.cmx \
- parsing/printer.cmx contrib/interface/translate.cmx \
- contrib/interface/vtp.cmx contrib/interface/xlate.cmx
contrib/interface/translate.cmo: contrib/interface/ascent.cmi parsing/ast.cmi \
interp/constrextern.cmi contrib/interface/ctast.cmo kernel/environ.cmi \
pretyping/evarutil.cmi pretyping/evd.cmi library/libobject.cmi \
@@ -2839,6 +2843,66 @@ contrib/jprover/jtunify.cmo: contrib/jprover/jtunify.cmi
contrib/jprover/jtunify.cmx: contrib/jprover/jtunify.cmi
contrib/jprover/opname.cmo: contrib/jprover/opname.cmi
contrib/jprover/opname.cmx: contrib/jprover/opname.cmi
+contrib/linear/ccidpc.cmo: proofs/clenv.cmi contrib/linear/dpctypes.cmi \
+ kernel/environ.cmi proofs/evar_refiner.cmi library/global.cmi \
+ toplevel/himsg.cmi tactics/hipattern.cmi library/libnames.cmi \
+ library/nameops.cmi kernel/names.cmi library/nametab.cmi lib/pp.cmi \
+ parsing/printer.cmi pretyping/rawterm.cmi pretyping/reductionops.cmi \
+ kernel/sign.cmi tactics/tacinterp.cmi proofs/tacmach.cmi \
+ tactics/tacticals.cmi tactics/tactics.cmi kernel/term.cmi \
+ pretyping/termops.cmi lib/util.cmi
+contrib/linear/ccidpc.cmx: proofs/clenv.cmx contrib/linear/dpctypes.cmx \
+ kernel/environ.cmx proofs/evar_refiner.cmx library/global.cmx \
+ toplevel/himsg.cmx tactics/hipattern.cmx library/libnames.cmx \
+ library/nameops.cmx kernel/names.cmx library/nametab.cmx lib/pp.cmx \
+ parsing/printer.cmx pretyping/rawterm.cmx pretyping/reductionops.cmx \
+ kernel/sign.cmx tactics/tacinterp.cmx proofs/tacmach.cmx \
+ tactics/tacticals.cmx tactics/tactics.cmx kernel/term.cmx \
+ pretyping/termops.cmx lib/util.cmx
+contrib/linear/dpc.cmo: contrib/linear/ccidpc.cmo toplevel/cerrors.cmi \
+ parsing/egrammar.cmi interp/genarg.cmi parsing/pcoq.cmi lib/pp.cmi \
+ parsing/pptactic.cmi proofs/proof_trees.cmi contrib/linear/prove.cmi \
+ proofs/refiner.cmi tactics/tacinterp.cmi proofs/tacmach.cmi \
+ tactics/tacticals.cmi tactics/tactics.cmi lib/util.cmi
+contrib/linear/dpc.cmx: contrib/linear/ccidpc.cmx toplevel/cerrors.cmx \
+ parsing/egrammar.cmx interp/genarg.cmx parsing/pcoq.cmx lib/pp.cmx \
+ parsing/pptactic.cmx proofs/proof_trees.cmx contrib/linear/prove.cmx \
+ proofs/refiner.cmx tactics/tacinterp.cmx proofs/tacmach.cmx \
+ tactics/tacticals.cmx tactics/tactics.cmx lib/util.cmx
+contrib/linear/dpctypes.cmo: kernel/names.cmi kernel/term.cmi \
+ contrib/linear/dpctypes.cmi
+contrib/linear/dpctypes.cmx: kernel/names.cmx kernel/term.cmx \
+ contrib/linear/dpctypes.cmi
+contrib/linear/general.cmo: contrib/linear/general.cmi
+contrib/linear/general.cmx: contrib/linear/general.cmi
+contrib/linear/graph.cmo: contrib/linear/graph.cmi
+contrib/linear/graph.cmx: contrib/linear/graph.cmi
+contrib/linear/kwc.cmo: contrib/linear/dpctypes.cmi \
+ contrib/linear/general.cmi contrib/linear/graph.cmi kernel/names.cmi \
+ contrib/linear/subst.cmi contrib/linear/unif.cmi lib/util.cmi
+contrib/linear/kwc.cmx: contrib/linear/dpctypes.cmx \
+ contrib/linear/general.cmx contrib/linear/graph.cmx kernel/names.cmx \
+ contrib/linear/subst.cmx contrib/linear/unif.cmx lib/util.cmx
+contrib/linear/lk_proofs.cmo: contrib/linear/dpctypes.cmi \
+ contrib/linear/general.cmi kernel/names.cmi contrib/linear/subst.cmi \
+ contrib/linear/unif.cmi
+contrib/linear/lk_proofs.cmx: contrib/linear/dpctypes.cmx \
+ contrib/linear/general.cmx kernel/names.cmx contrib/linear/subst.cmx \
+ contrib/linear/unif.cmx
+contrib/linear/prove.cmo: contrib/linear/dpctypes.cmi contrib/linear/kwc.cmo \
+ contrib/linear/lk_proofs.cmo contrib/linear/prove.cmi
+contrib/linear/prove.cmx: contrib/linear/dpctypes.cmx contrib/linear/kwc.cmx \
+ contrib/linear/lk_proofs.cmx contrib/linear/prove.cmi
+contrib/linear/subst.cmo: contrib/linear/dpctypes.cmi \
+ contrib/linear/general.cmi kernel/names.cmi contrib/linear/subst.cmi
+contrib/linear/subst.cmx: contrib/linear/dpctypes.cmx \
+ contrib/linear/general.cmx kernel/names.cmx contrib/linear/subst.cmi
+contrib/linear/unif.cmo: contrib/linear/dpctypes.cmi \
+ contrib/linear/general.cmi library/nameops.cmi contrib/linear/subst.cmi \
+ contrib/linear/unif.cmi
+contrib/linear/unif.cmx: contrib/linear/dpctypes.cmx \
+ contrib/linear/general.cmx library/nameops.cmx contrib/linear/subst.cmx \
+ contrib/linear/unif.cmi
contrib/omega/coq_omega.cmo: parsing/ast.cmi proofs/clenv.cmi \
kernel/closure.cmi tactics/contradiction.cmi interp/coqlib.cmi \
kernel/declarations.cmi library/declare.cmi kernel/environ.cmi \
@@ -2941,12 +3005,12 @@ contrib/romega/refl_omega.cmx: parsing/ast.cmx tactics/auto.cmx \
proofs/proof_type.cmx kernel/reduction.cmx kernel/sign.cmx \
proofs/tacmach.cmx tactics/tacticals.cmx tactics/tactics.cmx \
kernel/term.cmx lib/util.cmx
-contrib/xml/acic.cmo: kernel/names.cmi kernel/term.cmi
-contrib/xml/acic.cmx: kernel/names.cmx kernel/term.cmx
contrib/xml/acic2Xml.cmo: contrib/xml/acic.cmo contrib/xml/cic2acic.cmo \
kernel/names.cmi kernel/term.cmi lib/util.cmi contrib/xml/xml.cmi
contrib/xml/acic2Xml.cmx: contrib/xml/acic.cmx contrib/xml/cic2acic.cmx \
kernel/names.cmx kernel/term.cmx lib/util.cmx contrib/xml/xml.cmx
+contrib/xml/acic.cmo: kernel/names.cmi kernel/term.cmi
+contrib/xml/acic.cmx: kernel/names.cmx kernel/term.cmx
contrib/xml/cic2acic.cmo: contrib/xml/acic.cmo library/declare.cmi \
library/dischargedhypsmap.cmi contrib/xml/doubleTypeInference.cmi \
kernel/environ.cmi pretyping/evarutil.cmi pretyping/evd.cmi \
@@ -3001,8 +3065,6 @@ contrib/xml/proofTree2Xml.cmx: contrib/xml/acic.cmx contrib/xml/acic2Xml.cmx \
contrib/xml/xml.cmx
contrib/xml/unshare.cmo: contrib/xml/unshare.cmi
contrib/xml/unshare.cmx: contrib/xml/unshare.cmi
-contrib/xml/xml.cmo: contrib/xml/xml.cmi
-contrib/xml/xml.cmx: contrib/xml/xml.cmi
contrib/xml/xmlcommand.cmo: contrib/xml/acic.cmo contrib/xml/acic2Xml.cmo \
contrib/xml/cic2acic.cmo library/decl_kinds.cmo kernel/declarations.cmi \
library/declare.cmi kernel/environ.cmi pretyping/evd.cmi \
@@ -3029,6 +3091,8 @@ contrib/xml/xmlentries.cmx: toplevel/cerrors.cmx parsing/egrammar.cmx \
parsing/extend.cmx interp/genarg.cmx parsing/pcoq.cmx lib/pp.cmx \
parsing/pptactic.cmx tactics/tacinterp.cmx lib/util.cmx \
toplevel/vernacinterp.cmx contrib/xml/xmlcommand.cmx
+contrib/xml/xml.cmo: contrib/xml/xml.cmi
+contrib/xml/xml.cmx: contrib/xml/xml.cmi
tactics/tauto.cmo: parsing/grammar.cma
tactics/tauto.cmx: parsing/grammar.cma
tactics/newtauto.cmo: parsing/grammar.cma
@@ -3067,6 +3131,10 @@ contrib/jprover/jprover.cmo: parsing/grammar.cma
contrib/jprover/jprover.cmx: parsing/grammar.cma
contrib/cc/cctac.cmo: parsing/grammar.cma
contrib/cc/cctac.cmx: parsing/grammar.cma
+contrib/linear/ccidpc.cmo: parsing/grammar.cma
+contrib/linear/ccidpc.cmx: parsing/grammar.cma
+contrib/linear/dpc.cmo: parsing/grammar.cma
+contrib/linear/dpc.cmx: parsing/grammar.cma
parsing/lexer.cmo:
parsing/lexer.cmx:
parsing/q_util.cmo:
diff --git a/.depend.camlp4 b/.depend.camlp4
index c8dddc1328..9fc97cdd1d 100644
--- a/.depend.camlp4
+++ b/.depend.camlp4
@@ -17,6 +17,8 @@ contrib/extraction/g_extraction.ml: parsing/grammar.cma
contrib/xml/xmlentries.ml: parsing/grammar.cma
contrib/jprover/jprover.ml: parsing/grammar.cma
contrib/cc/cctac.ml: parsing/grammar.cma
+contrib/linear/ccidpc.ml: parsing/grammar.cma
+contrib/linear/dpc.ml: parsing/grammar.cma
parsing/lexer.ml:
parsing/q_util.ml:
parsing/q_coqast.ml:
diff --git a/Makefile b/Makefile
index 4ec92ca607..41b613d303 100644
--- a/Makefile
+++ b/Makefile
@@ -44,7 +44,7 @@ LOCALINCLUDES=-I config -I tools -I scripts -I lib -I kernel -I library \
-I contrib/ring -I contrib/xml \
-I contrib/extraction -I contrib/correctness \
-I contrib/interface -I contrib/fourier \
- -I contrib/jprover -I contrib/cc
+ -I contrib/jprover -I contrib/cc -I contrib/linear
MLINCLUDES=$(LOCALINCLUDES) -I $(MYCAMLP4LIB)
@@ -347,11 +347,24 @@ JPROVERCMO=\
CCCMO=contrib/cc/ccalgo.cmo contrib/cc/ccproof.cmo contrib/cc/cctac.cmo
-ML4FILES += contrib/jprover/jprover.ml4 contrib/cc/cctac.ml4
+LINEARCMO=\
+ contrib/linear/dpctypes.cmo \
+ contrib/linear/general.cmo \
+ contrib/linear/graph.cmo \
+ contrib/linear/subst.cmo \
+ contrib/linear/unif.cmo \
+ contrib/linear/lk_proofs.cmo \
+ contrib/linear/ccidpc.cmo \
+ contrib/linear/kwc.cmo \
+ contrib/linear/prove.cmo \
+ contrib/linear/dpc.cmo
+
+ML4FILES += contrib/jprover/jprover.ml4 contrib/cc/cctac.ml4 \
+ contrib/linear/ccidpc.ml4 contrib/linear/dpc.ml4
CONTRIB=$(OMEGACMO) $(ROMEGACMO) $(RINGCMO) $(FIELDCMO) \
$(FOURIERCMO) $(EXTRACTIONCMO) $(JPROVERCMO) $(XMLCMO) \
- $(CORRECTNESSCMO) $(CCCMO) $(USERCMO)
+ $(CORRECTNESSCMO) $(CCCMO) $(LINEARCMO) $(USERCMO)
CMA=$(CLIBS) $(CAMLP4OBJS)
CMXA=$(CMA:.cma=.cmxa)
diff --git a/contrib/linear/ccidpc.ml4 b/contrib/linear/ccidpc.ml4
new file mode 100755
index 0000000000..1e3ec39e48
--- /dev/null
+++ b/contrib/linear/ccidpc.ml4
@@ -0,0 +1,371 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i camlp4deps: "parsing/grammar.cma" i*)
+
+(*i $Id$ i*)
+
+open Dpctypes
+
+open Names
+open Nameops
+open Pp
+open Term
+open Termops
+open Environ
+open Himsg
+open Tacmach
+open Reductionops
+open Clenv
+open Tactics
+open Hipattern
+open Tacticals
+open Tactics
+open Util
+open Sign
+open Tacinterp
+
+(*
+let mmk = make_module_marker ["#Prelude.obj"]
+
+let and_pattern = put_pat mmk "(and ? ?)"
+let or_pattern = put_pat mmk "(or ? ?)"
+let not_pattern = put_pat mmk "(not ?)"
+let exist_pattern = put_pat mmk "(ex ? ?)"
+
+let and_head = put_pat mmk "and"
+let or_head = put_pat mmk "or"
+let not_head = put_pat mmk "not"
+let exist_head = put_pat mmk "ex"
+
+*)
+
+let op2bool=function Some _->true |None->false
+
+let match_with_imp_term t =
+ match kind_of_term t with
+ Prod (_,a,b)->
+ if not (dependent (mkRel 1) b) then
+ Some (a,b) else None
+ | _-> None
+
+let is_imp_term t=op2bool (match_with_imp_term t)
+
+let match_with_forall_term t =
+ match kind_of_term (whd_betaiota t) with
+ Prod (x,a,b)->
+ if dependent (mkRel 1) b then Some (x,a,b) else None
+ | _ -> None
+
+let is_forall_term t=op2bool (match_with_forall_term t)
+
+let constr_of_string s () =
+ Libnames.constr_of_reference (Nametab.locate (Libnames.qualid_of_string s))
+
+let id_ex=constr_of_string "Coq.Init.Logic.ex"
+
+let match_with_exist_term t=
+ match kind_of_term t with
+ App(t,v)->
+ if t=id_ex () && (Array.length v)=2 then
+ match kind_of_term v.(1) with
+ Lambda(na,a,b)->Some(na,a,b)
+ |_->assert false
+ else None
+ | _->None
+
+let is_exist_term t=op2bool (match_with_exist_term t)
+
+let id_not=constr_of_string "Coq.Init.Logic.not"
+
+let id_false=constr_of_string "Coq.Init.Logic.False"
+
+let match_with_not_term t=
+ match kind_of_term t with
+ App(t,v)->
+ if t=id_not () && (Array.length v)=1 then
+ Some v.(0)
+ else None
+ | Prod(_,a,b)->
+ if b=id_false () then
+ Some a
+ else None
+ | _->None
+
+
+let is_not_term t=op2bool (match_with_not_term t)
+
+let ctr = ref 0
+
+let gen_ident id = make_ident (atompart_of_id id) (incr ctr;Some !ctr)
+
+let gen_name a na =
+ let (Name id) = (named_hd Environ.empty_env a na)
+ in gen_ident id
+
+let dpc_of_cci_term lid =
+ let rec tradrec cciterm =
+ let (hd,args) = whd_betaiota_stack cciterm in
+ let dpcargs = List.map tradrec args
+ in (match kind_of_term hd with
+ Var id -> if dpcargs=[] then VAR id
+ else if List.mem id lid
+ then failwith "dpc_of_cci_term (not first order)"
+ else APP (VAR id :: dpcargs)
+
+ | (Const _ | Ind _ | Construct _) as t
+ -> if dpcargs=[] then GLOB (CN hd)
+ else APP (GLOB (CN hd) :: dpcargs)
+
+ | _ -> errorlabstrm "dpc_of_cci_term"
+ (str "Not a first order formula"))
+ in tradrec
+
+
+let cci_of_dpc_term tradsign sign =
+ let rec tradrec = function
+ VAR id ->
+ (try let (_,t,_)=lookup_named id tradsign in
+ match t with
+ Some t'-> t'
+ |None ->Term.mkVar id
+ with Not_found->Term.mkVar id)
+ | GLOB (ID id) -> Term.mkVar id
+ | GLOB (CN t) -> t
+ | APP (t::dpcargs) ->
+ let t' = tradrec t in
+ Term.applist(t', List.map tradrec dpcargs)
+ in tradrec
+
+
+let dpc_of_cci_fmla gls cciterm =
+ let rec tradrec lid cciterm =
+ match match_with_conjunction cciterm with
+ Some (_,[a;b])->Conj(tradrec lid a,tradrec lid b)
+ |_->
+ (match match_with_disjunction cciterm with
+ Some (_,[a;b])->Disj(tradrec lid a,tradrec lid b)
+ |_->
+ (match match_with_not_term cciterm with
+ Some a->Neg(tradrec lid a)
+ |_->
+ (match match_with_imp_term cciterm with
+ Some (a,b)->Imp (tradrec lid a,tradrec lid (pop b))
+ |_->
+ (match match_with_forall_term cciterm with
+ Some ((na,a,b) as trp)->
+ let id = gen_name a na in
+ let f=mkApp(mkLambda trp,[|mkVar id|]) in
+ ForAll(id,tradrec (id::lid) f)
+ |_->
+ (match match_with_exist_term cciterm with
+ Some ((na,a,b)as trp)->
+ let id = gen_name a na in
+ let f=mkApp(mkLambda trp,[|mkVar id|]) in
+ Exists(id,tradrec (id::lid) f)
+ |_->
+ let (hd,args) = whd_betaiota_stack cciterm in
+ let dpcargs = List.map (dpc_of_cci_term lid) args
+ in (match kind_of_term hd with
+ Var id -> if List.mem id lid
+ then errorlabstrm "dpc_of_cci_fmla"
+ (str "Quantification over a predicate")
+ else Atom((ID id,0),dpcargs)
+ | Ind _ | Construct _ | Const _
+ -> Atom( (CN hd,0) , dpcargs)
+ | _ -> errorlabstrm "dpc_of_cci_flma"
+ ((Printer.prterm_env
+ (Global.env_of_context (pf_hyps gls)) hd) ++
+ (spc ()) ++
+ (str "is not an atomic predicate"))))))))
+ in tradrec [] (whd_betaiota cciterm)
+
+let rec index x=function
+ []-> raise Not_found
+ | y::q-> if x=y then 0 else 1+(index x q)
+
+
+let rec alpha_term bl1 bl2 p_0 p_1 =
+ match p_0,p_1 with
+ ((VAR id1), (VAR id2)) ->
+ if not (List.mem id1 bl1) then
+ id1=id2
+ else
+ index id1 bl1 = index id2 bl2
+ | ((GLOB t1), (GLOB t2)) -> t1=t2
+ | ((APP al1), (APP al2)) ->
+ List.for_all2 (alpha_term bl1 bl2) al1 al2
+ | (_, _) -> false
+
+
+let forAllI gls=if is_forall_term (pf_concl gls) then
+ intro gls else tclFAIL 0 gls
+
+let forAllE id t gls =
+ let rgl=pf_whd_betadeltaiota gls (pf_type_of gls (mkVar id)) in
+ if is_forall_term rgl then
+ generalize [mkApp (mkVar id,[|t|])] gls else tclFAIL 0 gls
+
+let existE id gls =
+ let (_,_,t)=lookup_named id (pf_hyps gls) in
+ if is_exist_term t then
+ ((tclTHEN (simplest_elim (mkVar id))
+ (tclDO 2 (dImp None)))) gls
+ else tclFAIL 0 gls
+
+let negE id gls =
+ let (_,_,t)=lookup_named id (pf_hyps gls) in
+ if is_not_term t then
+ (simplest_elim (mkVar id)) gls
+ else tclFAIL 0 gls
+
+(*t exist_intro_head = put_pat mmk "ex_intro"*)
+
+let existI t gls =
+ let (wc,kONT) = Evar_refiner.startWalk gls in
+ let clause = mk_clenv_hnf_constr_type_of wc (pf_concl gls) in
+ let clause' = clenv_constrain_missing_args [t] clause
+ in res_pf kONT clause' gls
+
+
+let rec alpha_fmla bl1 bl2 p_0 p_1 =
+ match p_0,p_1 with
+ ((Atom((cn1,_),al1)), (Atom((cn2,_),al2))) ->
+ cn1=cn2 & List.for_all2 (alpha_term bl1 bl2) al1 al2
+ | ((Conj(a1,b1)),(Conj(a2,b2))) ->
+ alpha_fmla bl1 bl2 a1 a2 & alpha_fmla bl1 bl2 b1 b2
+
+ | ((Disj(a1,b1)),(Disj(a2,b2))) ->
+ alpha_fmla bl1 bl2 a1 a2 & alpha_fmla bl1 bl2 b1 b2
+
+ | ((Imp(a1,b1)),(Imp(a2,b2))) ->
+ alpha_fmla bl1 bl2 a1 a2 & alpha_fmla bl1 bl2 b1 b2
+
+ | ((Neg(a1)), (Neg(a2))) -> alpha_fmla bl1 bl2 a1 a2
+
+ | ((ForAll(x1,a1)), (ForAll(x2,a2))) ->
+ alpha_fmla (x1::bl1) (x2::bl2) a1 a2
+
+ | ((Exists(x1,a1)), (Exists(x2,a2))) ->
+ alpha_fmla (x1::bl1) (x2::bl2) a1 a2
+
+ | (_, _) -> false
+
+let alpha_eq (kspine,m) (jspine,n) = alpha_fmla kspine jspine m n
+
+let first_pred p =
+ let rec firstrec = function
+ [] -> error "first_pred"
+ | h::t -> if p h then h else firstrec t
+ in firstrec
+
+
+let find_fmla_left (kspine,f) (jspine,gl) =
+ let ids = pf_ids_of_hyps gl
+ and sign= pf_hyps gl in
+ first_pred
+ (fun id ->
+ let (_,_,t)=lookup_named id sign in
+ ( try alpha_eq (kspine,f)
+ (jspine,dpc_of_cci_fmla gl t)
+ with _ -> false)
+ ) ids
+
+
+let onNthClause tac n gls =
+ let cls = nth_clause n gls
+ in onClause tac cls gls
+
+
+let elimTypeFalse gls =
+ (elim_type (pf_global gls (id_of_string "False"))) gls
+
+
+let rec tradpf kspine jspine dpcpf gls =
+ match dpcpf with
+
+ Proof2(_,_,Axiom2 f) ->
+ let id = find_fmla_left (kspine,f) (jspine,gls)
+ in exact_no_check (mkVar id) gls
+
+ | Proof2(_,_,LWeakening2(_,pf)) -> trad kspine jspine pf gls
+
+ | Proof2(_,_,RWeakening2(_,pf)) ->
+ ( (tclTHEN (elimTypeFalse) (tradpf kspine jspine pf)) ) gls
+
+ | Proof2(_,_,RConj2(f1,pf1,f2,pf2)) ->
+ ((tclTHENS (dAnd None) ([trad kspine jspine pf1;
+ trad kspine jspine pf2]))) gls
+
+ | Proof2(_,_,LConj2(f1,f2,pf)) ->
+ let id = find_fmla_left (kspine,Conj(f1,f2)) (jspine,gls)
+ in ((tclTHEN (dAnd (Some id)) ((trad kspine jspine pf)))) gls
+
+ | Proof2(_,_,LDisj2(f1,pf1,f2,pf2)) ->
+ let id = find_fmla_left (kspine,Disj(f1,f2)) (jspine,gls)
+ in (match pf1 with
+ Proof2(_,[],_) -> ((tclTHENS (orE id)
+ ([ ((tclTHEN (elimTypeFalse) (trad kspine jspine pf1)));
+ trad kspine jspine pf2]))) gls
+ | _ -> ((tclTHENS (orE id)
+ ([ trad kspine jspine pf1;
+ ((tclTHEN (elimTypeFalse) (trad kspine jspine pf2)))]))) gls
+ )
+
+ | Proof2(_,_,RImp2(f1,f2,pf)) ->
+ ((tclTHEN (dImp None) ((trad kspine jspine pf)))) gls
+
+ | Proof2(_,_,LImp2(f1,pf1,f2,pf2)) ->
+ let id = find_fmla_left (kspine,Imp(f1,f2)) (jspine,gls)
+ in ((tclTHENS (dImp (Some id))
+ ([trad kspine jspine pf2;
+ trad kspine jspine pf1]))) gls
+
+ | Proof2(_,_,RForAll2(kid,f,pf)) ->
+ ((tclTHEN forAllI
+ ((onLastHyp (fun jid ->
+ trad (kid::kspine) (jid::jspine) pf))))) gls
+
+ | Proof2(_,_,LForAll2(kid,kterm,f,pf)) ->
+ let jterm = cci_of_dpc_term (pf_hyps gls) (kspine,jspine) kterm in
+ let id = find_fmla_left (kspine,ForAll(kid,f)) (jspine,gls)
+ in ((tclTHEN (forAllE id jterm)
+ (trad kspine jspine pf))) gls
+
+ | Proof2(_,_,LExists2(kid,f,pf)) ->
+ let id = find_fmla_left (kspine,Exists(kid,f)) (jspine,gls)
+ in ((tclTHEN (existE id)
+ ((onNthClause (fun (Some jid) ->
+ trad (kid::kspine) (jid::jspine) pf)
+ (-2))))) gls
+
+ | Proof2(_,_,RExists2(kid,kterm,f,pf)) ->
+ let jterm = cci_of_dpc_term (pf_hyps gls) (kspine,jspine) kterm
+ in ((tclTHEN (existI jterm) (tradpf kspine jspine pf))) gls
+
+ | Proof2(_,_,RDisj2(f1,f2,Proof2(_,_,RWeakening2(f3,pf)))) ->
+ if alpha_eq (kspine,f1) (kspine,f3) then
+ ((tclTHEN (right Rawterm.NoBindings) (tradpf kspine jspine pf))) gls
+ else if alpha_eq (kspine,f2) (kspine,f3) then
+ ((tclTHEN (left Rawterm.NoBindings) (tradpf kspine jspine pf))) gls
+ else error "Not Intuitionistic, eh?"
+
+ | Proof2(_,_,RNeg2(f,pf)) ->
+ ((tclTHEN ((tclTHEN (red_in_concl) (Tactics.intro))) (tradpf kspine jspine pf))) gls
+
+ | Proof2(_,_,LNeg2(f,pf)) ->
+ let id = find_fmla_left (kspine,Neg(f)) (jspine,gls)
+ in ((tclTHEN (negE id) (tradpf kspine jspine pf))) gls
+
+ | _ -> error "tradpf : Not an intuitionistic proof !"
+
+and trad kspine jspine dpcpf gls =
+ tradpf kspine jspine dpcpf gls
+
+
+(* $Id$ *)
diff --git a/contrib/linear/dpc.ml4 b/contrib/linear/dpc.ml4
new file mode 100755
index 0000000000..ba7bc884d4
--- /dev/null
+++ b/contrib/linear/dpc.ml4
@@ -0,0 +1,64 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i camlp4deps: "parsing/grammar.cma" i*)
+
+(*i $Id$ i*)
+
+open Pp
+open Util
+
+open Proof_trees
+open Tacmach
+open Tactics
+open Tacinterp
+open Tacticals
+open Prove
+open Ccidpc
+
+let rec intros_forall gls =
+ let t = pf_concl gls
+ in if is_forall_term t
+ then ((tclTHEN forAllI (intros_forall))) gls
+ else tclIDTAC gls
+
+let dPC_nq gls =
+ let f = dpc_of_cci_fmla gls (pf_concl gls) in
+ try let pf = prove_f f in
+ tradpf [] [] pf gls
+ with Not_provable_in_DPC s -> errorlabstrm "dpc__DPC_nq"
+ (str "Not provable in Direct Predicate Calculus")
+
+ | No_intuitionnistic_proof n -> errorlabstrm "dpc__DPC_nq"
+ ((str "Found ") ++
+ (str (string_of_int n)) ++
+ (str " classical proof(s) but no intuitionnistic one !"))
+
+
+let dPC =
+ ((tclTHEN (intros_forall) (dPC_nq)))
+
+
+let dPC_l lcom =
+ (tclTHEN (intros_forall)
+ (tclTHEN (generalize lcom) (dPC)))
+
+(*
+let dPC_tac = hide_atomic_tactic "DPC" dPC
+
+let dPC_l_tac = hide_tactic "DPC_l"
+ (fun lcom -> dPC_l lcom)
+*)
+
+TACTIC EXTEND Linear
+[ "Linear" ]->[(dPC)]
+|[ "Linear" "with" ne_constr_list(l) ] -> [(dPC_l l)]
+END
+
+
+
diff --git a/contrib/linear/dpctypes.ml b/contrib/linear/dpctypes.ml
new file mode 100644
index 0000000000..b21bd67e4a
--- /dev/null
+++ b/contrib/linear/dpctypes.ml
@@ -0,0 +1,60 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $Id$ *)
+
+
+open Names
+open Term
+
+type constname =
+ ID of identifier
+ | SK of identifier
+ | CN of constr
+
+
+type atom_id = constname * int
+
+type term = VAR of identifier
+ | GLOB of constname
+ | APP of term list
+
+type formula = Atom of atom_id * (term list)
+ | Neg of formula
+ | Imp of formula * formula
+ | Conj of formula * formula
+ | Disj of formula * formula
+ | ForAll of identifier * formula
+ | Exists of identifier * formula
+
+type sequent = Seq of formula list
+
+type sfla = Po of formula
+ | No of formula
+
+exception Impossible_case
+
+type lkproof2 = Proof2 of (formula list) * (formula list) * rule2
+ and rule2 =
+ Axiom2 of formula
+ | RWeakening2 of formula * lkproof2
+ | LWeakening2 of formula * lkproof2
+ | RNeg2 of formula * lkproof2
+ | LNeg2 of formula * lkproof2
+ | RConj2 of formula * lkproof2 * formula * lkproof2
+ | LConj2 of formula * formula * lkproof2
+ | RDisj2 of formula * formula * lkproof2
+ | LDisj2 of formula * lkproof2 * formula * lkproof2
+ | RImp2 of formula * formula * lkproof2
+ | LImp2 of formula * lkproof2 * formula * lkproof2
+ | RForAll2 of identifier * formula * lkproof2
+ | LForAll2 of identifier * term * formula * lkproof2
+ | RExists2 of identifier * term * formula * lkproof2
+ | LExists2 of identifier * formula * lkproof2
+
+
diff --git a/contrib/linear/dpctypes.mli b/contrib/linear/dpctypes.mli
new file mode 100755
index 0000000000..7115cf5199
--- /dev/null
+++ b/contrib/linear/dpctypes.mli
@@ -0,0 +1,59 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $Id$ *)
+
+open Names
+open Term
+
+type constname =
+ ID of identifier
+ | SK of identifier
+ | CN of constr
+
+
+type atom_id = constname * int
+
+type term = VAR of identifier
+ | GLOB of constname
+ | APP of term list
+
+type formula = Atom of atom_id * (term list)
+ | Neg of formula
+ | Imp of formula * formula
+ | Conj of formula * formula
+ | Disj of formula * formula
+ | ForAll of identifier * formula
+ | Exists of identifier * formula
+
+type sequent = Seq of formula list
+
+type sfla = Po of formula
+ | No of formula
+
+exception Impossible_case
+
+type lkproof2 = Proof2 of (formula list) * (formula list) * rule2
+ and rule2 =
+ Axiom2 of formula
+ | RWeakening2 of formula * lkproof2
+ | LWeakening2 of formula * lkproof2
+ | RNeg2 of formula * lkproof2
+ | LNeg2 of formula * lkproof2
+ | RConj2 of formula * lkproof2 * formula * lkproof2
+ | LConj2 of formula * formula * lkproof2
+ | RDisj2 of formula * formula * lkproof2
+ | LDisj2 of formula * lkproof2 * formula * lkproof2
+ | RImp2 of formula * formula * lkproof2
+ | LImp2 of formula * lkproof2 * formula * lkproof2
+ | RForAll2 of identifier * formula * lkproof2
+ | LForAll2 of identifier * term * formula * lkproof2
+ | RExists2 of identifier * term * formula * lkproof2
+ | LExists2 of identifier * formula * lkproof2
+
+(* $Id$ *)
diff --git a/contrib/linear/general.ml b/contrib/linear/general.ml
new file mode 100755
index 0000000000..5b998c5afa
--- /dev/null
+++ b/contrib/linear/general.ml
@@ -0,0 +1,41 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $Id$ *)
+
+let substract l1 l2=
+ let rec sub_aux=function
+ []->[]
+ | x::q->if List.mem x l2 then sub_aux q else x::(sub_aux q)
+ in sub_aux l1
+
+let rec union l1=function
+ []->l1
+ | x::q-> if List.mem x l1 then union l1 q else x::(union l1 q)
+
+(*** glue : make the concatenation of the lists of a lists list *****)
+
+let rec glue = function
+ (l::ll) -> union l (glue ll)
+ | [] -> []
+
+(*** disjoint l1 l2 : returns true if the lists l1 and l2 are disjoint ******)
+
+let disjoint l1 l2 =
+ let rec disjoint_rec = function
+ (a::ll1) -> if List.mem a l2 then false else disjoint_rec ll1
+ | [] -> true
+ in disjoint_rec l1
+
+(*** such_that : 'a list -> ('a -> bool) -> 'a list *******)
+
+let such_that l p =
+ let rec such_rec = function
+ a::ll -> if (p a) then a::(such_rec ll) else such_rec ll
+ | [] -> []
+ in such_rec l
diff --git a/contrib/linear/general.mli b/contrib/linear/general.mli
new file mode 100755
index 0000000000..8acf596613
--- /dev/null
+++ b/contrib/linear/general.mli
@@ -0,0 +1,16 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $Id$ i*)
+
+val substract : 'a list -> 'a list -> 'a list
+val union : 'a list -> 'a list -> 'a list
+val glue : 'a list list -> 'a list
+val disjoint : 'a list -> 'a list -> bool
+val such_that : 'a list -> ('a -> bool) -> 'a list
+
diff --git a/contrib/linear/graph.ml b/contrib/linear/graph.ml
new file mode 100755
index 0000000000..94ddcbd97d
--- /dev/null
+++ b/contrib/linear/graph.ml
@@ -0,0 +1,70 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $Id$ i*)
+
+(* Given a DIRECTED graph G represented by a list of
+ (x , [neighbours of x])
+ then (have_cycle G) returns true if G has a nontrivial cycle.
+ Remark : G is not necessarly connected. *******)
+
+type mark = NotMarked | OnThePath | AlreadyVisited;;
+
+let df_cycle v marks g =
+ let rec df_cycle_rec x =
+ (List.assoc x marks) := OnThePath;
+ let nx = List.assoc x g
+ in let nb_marks =
+ List.fold_left (fun s x -> if !(List.assoc x marks)=OnThePath
+ then s+1 else s) 0 nx
+ in if nb_marks>0
+ then true
+ else let isc = List.fold_left (fun r y -> if r then true
+ else if !(List.assoc y marks)=AlreadyVisited
+ then false
+ else (df_cycle_rec y)) false nx
+ in if isc then true
+ else ((List.assoc x marks) := AlreadyVisited; false)
+ and df_init ls = match ls with
+ (s::lls) -> if (!(List.assoc s marks)=NotMarked)
+ & ((List.length (List.assoc s g))>0)
+ then (if df_cycle_rec s
+ then true
+ else df_init lls)
+ else df_init lls
+ | [] -> false
+ in df_init v;;
+
+let have_cycle g =
+ let v = List.map (fun (x,_) -> x) g
+ in let marks = List.map (fun x -> (x,ref NotMarked)) v
+ in if List.length g<2
+ then false
+ else let x0 = fst (List.hd g)
+ in df_cycle v marks g;;
+
+(* Examples...
+
+ have_cycle [(1,[2;3]); (2,[3]); (3,[])];; (false)
+
+ have_cycle [(1,[2;3]); (2,[1;3]); (3,[1;2])];; (true)
+
+ have_cycle [(1 , [6]);
+ (2 , [3;4;5]);
+ (3 , [2;5]);
+ (4 , [2]);
+ (5 , [2;3]);
+ (6 , [1])];; (true)
+
+ have_cycle [(2,[3]); (4,[]); (1,[4]); (3,[])];; (false)
+
+ have_cycle [(3,[1;2]); (4,[]); (2,[4]); (1,[4])];; (false)
+
+*)
+
+
diff --git a/contrib/linear/graph.mli b/contrib/linear/graph.mli
new file mode 100755
index 0000000000..63ae558e54
--- /dev/null
+++ b/contrib/linear/graph.mli
@@ -0,0 +1,12 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $Id$ i*)
+
+val have_cycle : ('a * 'a list) list -> bool;;
+
diff --git a/contrib/linear/kwc.ml b/contrib/linear/kwc.ml
new file mode 100755
index 0000000000..13a9b85400
--- /dev/null
+++ b/contrib/linear/kwc.ml
@@ -0,0 +1,233 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $Id$ i*)
+
+open Util
+open Names
+
+open General
+open Dpctypes
+open Subst
+open Unif
+open Graph
+
+(* Herbrand form *************)
+
+let h_fun v ex f =
+ let lt = List.map (fun x -> VAR(x)) ex
+ in subst v (APP (GLOB (SK v)::lt)) f
+
+let free_her fv f =
+ let rec fh_rec f = function
+ v::ll -> let f0 = subst v (APP [GLOB (SK v)]) f
+ in fh_rec f0 ll
+ | [] -> f
+ in fh_rec f fv
+
+let herbrand f =
+ let rec h_rec ex sign f = match f with
+ ForAll(v,f1) -> if sign then (h_rec ex sign (h_fun v ex f1))
+ else (h_rec (v::ex) sign f1)
+ | Exists(v,f1) -> if sign then (h_rec (v::ex) sign f1)
+ else (h_rec ex sign (h_fun v ex f1))
+ | Neg(f1) -> let (e,h) = (h_rec ex ((not (sign))) f1)
+ in (e , Neg h)
+ | Atom(s,lt) -> (ex,Atom(s,lt))
+ | Imp(f1,f2) -> (let (ex1,h1) = (h_rec ex ((not (sign))) f1)
+ and (ex2,h2) = (h_rec ex sign f2)
+ in (union ex1 ex2,Imp(h1,h2)))
+ | Conj(f1,f2) -> (let (ex1,h1) = (h_rec ex sign f1)
+ and (ex2,h2) = (h_rec ex sign f2)
+ in (union ex1 ex2,Conj(h1,h2)))
+ | Disj(f1,f2) -> (let (ex1,h1) = (h_rec ex sign f1)
+ and (ex2,h2) = (h_rec ex sign f2)
+ in (union ex1 ex2,Disj(h1,h2)))
+ in let (ex,f0) = h_rec [] true f
+ in let fv = free_var_formula f
+ in (ex,free_her fv f0)
+
+let separate f =
+ let n = ref 0
+ in let rec sep_rec f = match f with
+ Atom((s,0),lt) -> n := !n+1;
+ Atom((s,!n),lt)
+ | Atom((s,_),_) -> anomaly "separate"
+ | Neg(f1) -> Neg(sep_rec f1)
+ | ForAll(s,f1) -> ForAll(s,sep_rec f1)
+ | Exists(s,f1) -> Exists(s,sep_rec f1)
+ | Imp(f1,f2)-> Imp(sep_rec f1,sep_rec f2)
+ | Conj(f1,f2) -> Conj(sep_rec f1,sep_rec f2)
+ | Disj(f1,f2) -> Disj(sep_rec f1,sep_rec f2)
+ in sep_rec f
+
+(* Searching for paths... *********)
+
+let lit_conj f =
+ let rec lc_rec sign = function
+ Atom(_,_) as a -> if sign then ([a],[],[]) else ([],[a],[])
+ | Neg(f1) -> lc_rec ((not (sign))) f1
+ | Conj(f1,f2) -> let (p1,n1,c1) = lc_rec sign f1
+ and (p2,n2,c2) = lc_rec sign f2
+ in let c = if sign then [((f1,f2),(p1@n1,p2@n2))]
+ else []
+ in (p1@p2,n1@n2,c@c1@c2)
+ | Disj(f1,f2) -> let (p1,n1,c1) = lc_rec sign f1
+ and (p2,n2,c2) = lc_rec sign f2
+ in let c = if sign then []
+ else [((f1,f2),(p1@n1,p2@n2))]
+ in (p1@p2,n1@n2,c@c1@c2)
+ | Imp(f1,f2) -> let (p1,n1,c1) = lc_rec ((not (sign))) f1
+ and (p2,n2,c2) = lc_rec sign f2
+ in let c = if sign then []
+ else [((f1,f2),(p1@n1,p2@n2))]
+ in (p1@p2,n1@n2,c@c1@c2)
+ | _ -> raise Impossible_case
+ in lc_rec true f
+
+
+(* Finding all matches ********)
+
+let mb p q =
+ let rec mb_rec = function
+ (_,(lf1,lf2))::ll -> ((not(( ((List.mem p lf1) & (List.mem q lf2))
+ or ((List.mem q lf1) & (List.mem p lf2))))) )
+ & (mb_rec ll)
+ | [] -> true
+ in mb_rec
+
+
+let all_matches pos neg lcj =
+ let rec all_matches_p (x,y) = function
+ ((Atom (x_0,x_1)) as q::neg1) ->
+ let lm = try [((Atom (x,y)),q,unif_atoms (x,y) (x_0,x_1))]
+ with Not_unifiable -> []
+ in if mb (Atom (x,y)) q lcj then lm@(all_matches_p (x,y) neg1)
+ else (all_matches_p (x,y) neg1)
+ | _ -> []
+ and all_matches_rec = function
+ ((Atom (x_0,x_1))::pos1) -> (all_matches_p (x_0,x_1) neg)@(all_matches_rec pos1)
+ | _ -> []
+ in all_matches_rec pos
+
+(* combine_path P L : returns the least path containing all the matches
+ in P and L. If no such path exists, it raises
+ CP_error *********)
+
+exception CP_error
+
+let rec lit_unicity = function
+ (p::ll) -> if List.mem p ll then false else lit_unicity ll
+ | [] -> true
+
+let combine_path (m1,u1) (m2,u2) =
+ let lm = union m1 m2
+ in let llt = List.map (fun (p,q,_) -> [p;q]) lm
+ in let lt = List.flatten llt
+ in if lit_unicity lt
+ then let u = try up u1 u2 with Up_error -> raise CP_error
+ in (lm , u)
+ else raise CP_error
+
+(* lit_in_matches : formula list -> (match list) -> bool *****)
+
+let lit_in_matches lF ml =
+ let rec lim_rec = function
+ ((p,q,_)::mmll) -> if (List.mem p lF) or (List.mem q lF)
+ then true
+ else lim_rec mmll
+ | [] -> false
+ in lim_rec ml
+
+(* 16.III.94 *********)
+(* Simple Depth First Search (p.138) *******)
+(* NB : path = match list * unifier ********)
+
+let rec matches_pos p = function
+ ((p1,q,u) as m::mM) -> if p=p1
+ then [([m] , u)]@(matches_pos p mM)
+ else matches_pos p mM
+ | [] -> []
+
+let rec matches_neg q = function
+ ((p,q1,u) as m::mM) -> if q=q1
+ then [([m] , u)]@(matches_neg q mM)
+ else matches_neg q mM
+ | [] -> []
+
+let uncovered (ml,_) lcj =
+ let rec uncov_rec = function
+ (((f1,f2),(lf1,lf2))::llccjj) ->
+ let sat1 = lit_in_matches lf1 ml
+ in let sat2 = lit_in_matches lf2 ml
+ in if sat1 & ((not (sat2)))
+ then (f2,lf2)::(uncov_rec llccjj)
+ else if sat2 & ((not (sat1)))
+ then (f1,lf1)::(uncov_rec llccjj)
+ else (uncov_rec llccjj)
+ | [] -> []
+ in uncov_rec lcj
+
+let paths pos neg m lcj =
+ let rec paths_rec = function
+ ((_,_,u) as m_0::mM) -> (extend ([m_0],u))@(paths_rec mM)
+ | [] -> []
+ and extension p (f1,lf1) =
+ let lm = glue (List.map (fun x -> if List.mem x pos
+ then matches_pos x m
+ else matches_neg x m) lf1)
+ in let rec ext_rec = function
+ (l::ll) ->( try (combine_path p l)::(ext_rec ll)
+ with CP_error -> ext_rec ll
+ )
+ | [] -> []
+ in ext_rec lm
+ and extend p =
+ let uc = uncovered p lcj
+ in if uc = []
+ then [p]
+ else glue (List.map (fun x -> (glue (List.map extend (extension p x)))) uc)
+ in paths_rec m
+
+(* Dealing with cycles... ******)
+
+let conj_graph lm lc lt =
+ let rec nb_of_x = function
+ (p::lpp) -> (try let q = List.assoc p lm in q::(nb_of_x lpp)
+ with Not_found -> nb_of_x lpp)
+ | [] -> []
+ and nb_rec x = function
+ ((l1,l2)::lcc) ->
+ if List.mem x l1
+ then (nb_of_x l2)@(nb_rec x lcc)
+ else if List.mem x l2
+ then (nb_of_x l1)@(nb_rec x lcc)
+ else nb_rec x lcc
+ | [] -> []
+ and conj_graph_rec = function
+ (p::ll) -> (p,nb_rec p lc)::(conj_graph_rec ll)
+ | [] -> []
+ in conj_graph_rec lt
+
+let is_cyclic_path lcj (lmu,u) =
+ let lm = List.flatten (List.map (fun (p,q,_) -> [(p,q);(q,p)]) lmu)
+ in let lc = List.map (fun (_,pl) -> pl) lcj
+ in let lt = List.map (fun (p,_) -> p) lm
+ in let g = conj_graph lm lc lt
+ in have_cycle g
+
+let good_paths lcj lp =
+ let rec good_paths_rec = function
+ (p::pp) -> if is_cyclic_path lcj p
+ then good_paths_rec pp
+ else p::(good_paths_rec pp)
+ | [] -> []
+ in good_paths_rec lp
+
+
+
diff --git a/contrib/linear/lk_proofs.ml b/contrib/linear/lk_proofs.ml
new file mode 100755
index 0000000000..e4ee298072
--- /dev/null
+++ b/contrib/linear/lk_proofs.ml
@@ -0,0 +1,730 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $Id$ i*)
+
+open Names
+
+open General
+open Dpctypes
+open Subst
+open Unif
+
+let proj = function
+ (Po x) -> x
+ | (No x) -> x
+
+
+let all_lit_sfla f =
+ all_lit (proj f)
+
+let sat p t =
+ let f = proj t
+ in let lt = all_lit f
+ in let rec sat_rec = function
+ ((p,q,_)::lm) -> if (List.mem p lt) or (List.mem q lt)
+ then true
+ else sat_rec lm
+ | [] -> false
+ in sat_rec (fst p)
+
+let decomp s p =
+ let rec decomp_rec = function
+ (t1::llTT) ->
+ let (ns,disj,at,nat,conj,rneg,lneg) = decomp_rec llTT
+ in if (not ((sat p t1)))
+ then (t1::ns,disj,at,nat,conj,rneg,lneg)
+ else (match t1 with
+ Po(Atom(_)) -> (ns,disj,t1::at,nat,conj,rneg,lneg)
+ | No(Atom(_)) -> (ns,disj,at,t1::nat,conj,rneg,lneg)
+ | Po(Neg(_)) -> (ns,disj,at,nat,conj,t1::rneg,lneg)
+ | No(Neg(_)) -> (ns,disj,at,nat,conj,rneg,t1::lneg)
+ | Po(Conj(_,_)) -> (ns,disj,at,nat,t1::conj,rneg,lneg)
+ | No(Disj(_,_)) -> (ns,disj,at,nat,t1::conj,rneg,lneg)
+ | No(Imp(_,_)) -> (ns,disj,at,nat,t1::conj,rneg,lneg)
+ | Po(Disj(_,_)) -> (ns,t1::disj,at,nat,conj,rneg,lneg)
+ | Po(Imp(_,_)) -> (ns,t1::disj,at,nat,conj,rneg,lneg)
+ | No(Conj(_,_)) -> (ns,t1::disj,at,nat,conj,rneg,lneg)
+ | _ -> failwith "decomp_rec : quantified formula !"
+ )
+ | [] -> ([],[],[],[],[],[],[])
+ in decomp_rec s
+
+let rec apply_weakening ((Proof2(sq1,sq2,_)) as pr) = function
+ (t::llTT) -> (match t with
+ (Po(f)) -> apply_weakening (Proof2(sq1,f::sq2,RWeakening2(f,pr))) llTT
+ | (No(f)) -> apply_weakening (Proof2(f::sq1,sq2,LWeakening2(f,pr))) llTT
+ )
+ | [] -> pr
+
+let one_disj_comp = function
+ Po(Disj(f1,f2)) -> (Po(f1),Po(f2))
+ | No(Conj(f1,f2)) -> (No(f1),No(f2))
+ | Po(Imp(f1,f2)) -> (No(f1),Po(f2))
+ | _ -> failwith "Not a disjunction in one_disj_comp !"
+
+
+let apply_one_disj ((Proof2(sq1,sq2,r)) as lk) d =
+ (match d with
+ Po(Disj(f1,f2)) ->
+ let sq2' = substract sq2 [f1;f2]
+ in (Proof2(sq1,Disj(f1,f2)::sq2',RDisj2(f1,f2,lk)))
+ | No(Conj(f1,f2)) ->
+ let sq1' = substract sq1 [f1;f2]
+ in (Proof2(Conj(f1,f2)::sq1',sq2,LConj2(f1,f2,lk)))
+ | Po(Imp(f1,f2)) ->
+ let sq1' = substract sq1 [f1]
+ and sq2' = substract sq2 [f2]
+ in (Proof2(sq1',Imp(f1,f2)::sq2',RImp2(f1,f2,lk)))
+ | _ -> failwith "Not a disjunction in apply_one_disj !"
+ )
+
+let rec apply_disj lk = function
+ (d::ld) -> let lk1 = apply_disj lk ld
+ in apply_one_disj lk1 d
+ | [] -> lk
+
+let find_axiom (at,nat) p =
+ let rec find_axiom_rec = function
+ ((a,b,_)::lm) -> if (List.mem (Po a) at) & (List.mem (No b) nat)
+ then (a,b)
+ else find_axiom_rec lm
+ | [] -> raise Not_found
+ in find_axiom_rec (fst p)
+
+let sep_at at llt (lmu,_) =
+ let lm = List.map (fun (p,q,_) -> (p,q)) lmu
+ in let rec sep_at_rec = function
+ ((Po a)::ll) -> let (l1,l2) = sep_at_rec ll
+ in if (try let b = List.assoc a lm in List.mem b llt
+ with Not_found -> false)
+ then ((Po a)::l1,l2)
+ else (l1,(Po a)::l2)
+ | [] -> ([],[])
+ in sep_at_rec at
+
+let sep_nat nat llt (lmu,_) =
+ let lm = List.map (fun (p,q,_) -> (q,p)) lmu
+ in let rec sep_nat_rec = function
+ ((No a)::ll) -> let (l1,l2) = sep_nat_rec ll
+ in if (try let b = List.assoc a lm in List.mem b llt
+ with Not_found -> false)
+ then ((No a)::l1,l2)
+ else (l1,(No a)::l2)
+ | [] -> ([],[])
+ in sep_nat_rec nat
+
+let sep_neg neg llt (lmu,_) =
+ let lm = glue (List.map (fun (p,q,_) -> [(p,q);(q,p)]) lmu)
+ in let rec connect = function
+ p::pp -> if (try let q = List.assoc p lm in List.mem q llt
+ with Not_found -> false)
+ then true
+ else connect pp
+ | [] -> false
+ in let rec sep_neg_rec = function
+ (g::ll) -> let (l1,l2) = sep_neg_rec ll
+ in let lit = all_lit_sfla g
+ in if connect lit then (g::l1,l2)
+ else (l1,g::l2)
+ | [] -> ([],[])
+ in sep_neg_rec neg
+
+(*** connect_graph : tree list -> path -> (tree,tree list,tree list) list
+ etant donnee une liste de conjonctions et un path,
+ rend le graphe des connections des formules conjonctives
+ sous la forme d'une liste de
+ (conjonction C, conjonctions reliees a C par la gauche,
+ conjonctions reliees a C par la droite) **********)
+
+let connect_graph conj (lmu,_) =
+ let lm = glue (List.map (fun (p,q,_) -> [(p,q);(q,p)]) lmu)
+ in let fun_lit = function
+ Po(Conj(f1,f2)) -> (all_lit f1,all_lit f2)
+ | No(Disj(f1,f2)) -> (all_lit f1,all_lit f2)
+ | No(Imp(f1,f2)) -> (all_lit f1,all_lit f2)
+ | _ -> failwith "Not a conjunction in connect_graph !"
+ in let lt = List.map (fun x -> (x,fun_lit x)) conj
+ in let in_which b = let rec in_which_rec = function
+ ((c,(l1,l2))::ll) -> if (List.mem b l1) or (List.mem b l2)
+ then c else in_which_rec ll
+ | [] -> raise Not_found
+ in in_which_rec lt
+ in let rec fun_nb c = function
+ (a::ll) -> let lnb = fun_nb c ll
+ in (try let b = List.assoc a lm
+ in let c1 = in_which b
+ in if c1=c then lnb else c1::lnb
+ with Not_found -> lnb)
+ | [] -> []
+ in let fun_cg c = let (l1,l2) = List.assoc c lt
+ in (fun_nb c l1,fun_nb c l2)
+ in List.map (fun x -> let (l1,l2) = fun_cg x in (x,l1,l2)) conj
+
+let cut_path (lm,u) lt =
+ let rec cut_path_rec = function
+ ((p,q,_) as m::llmm) -> let (llmm1,llmm2) = cut_path_rec llmm
+ in if (List.mem p lt) or (List.mem q lt)
+ then (m::llmm1,llmm2)
+ else (llmm1,m::llmm2)
+ | [] -> ([],[])
+ in let (lm1,lm2) = cut_path_rec lm
+ in ((lm1,u),(lm2,u))
+
+(*** sep_path : (at,nat,conj) -> path -> tree,(sequent,path),(sequent,path)
+ etant donnes (at,nat,conj) et p, fait la separation en deux couples
+ (sequent,path) correspondant aux deux membres d'une conjonction
+ et rend egalement la conjonction en question ********)
+
+let sep_path (at,nat,conj,rneg,lneg) p =
+ let g = connect_graph conj p
+ in let rec find_all_X0 = function
+ ((x,l1,l2) as gd::ll) -> if disjoint l1 l2 then
+ gd::(find_all_X0 ll)
+ else find_all_X0 ll
+ | [] -> []
+ in let all_X0 = find_all_X0 g
+ in let rec find_X0 = function
+ [x] -> x
+ | ((Po(Conj _),_,_) as c::_) -> c (** on recherche d'abord A/\B **)
+ | _::ll -> find_X0 ll
+ in let (x0,l1,l2) = if all_X0=[] then
+ failwith "Can't find X0 in sep_path ! (impossible case)"
+ else find_X0 all_X0
+ in let (g,d) = (match x0 with
+ Po(Conj(f1,f2)) -> (Po(f1),Po(f2))
+ | No(Disj(f1,f2)) -> (No(f1),No(f2))
+ | No(Imp(f1,f2)) -> (Po(f1),No(f2))
+ | _ -> failwith "Not a conjunction in sep_path !")
+ in let s1 = g::l1
+ in let s2 = d::(substract conj (x0::l1))
+ in let litS1 = glue (List.map (fun x -> all_lit_sfla x) s1)
+ in let (at1,at2) = sep_at at litS1 p
+ and (nat1,nat2) = sep_nat nat litS1 p
+ in let neg = lneg @ (List.map (fun (Po (Neg f)) -> (No f)) rneg)
+ in let (neg1,neg2) = sep_neg neg litS1 p
+ in let lit_at1 = List.map proj at1
+ and lit_nat1 = List.map proj nat1
+ and lit_neg1 = List.map proj neg1
+ in let (p1,p2) = cut_path p (lit_at1@lit_nat1@lit_neg1@litS1)
+ in let sq1 = s1 @ at1 @ nat1 @ neg1
+ in let sq2 = s2 @ at2 @ nat2 @ neg2
+ in (x0,(sq1,p1),(sq2,p2))
+
+let conj_case x0 ((Proof2(sq11,sq12,rl1)) as pr1)
+ ((Proof2(sq21,sq22,rl2)) as pr2) =
+ (match x0 with
+ Po(Conj(f1,f2)) ->
+ let sq2 = (substract sq12 [f1])@(substract sq22 [f2])
+ in (Proof2(sq11@sq21,Conj(f1,f2)::sq2,
+ RConj2(f1,pr1,f2,pr2)))
+ | No(Disj(f1,f2)) ->
+ let sq1 = (substract sq11 [f1])@(substract sq21 [f2])
+ in (Proof2(Disj(f1,f2)::sq1,sq12@sq22,
+ LDisj2(f1,pr1,f2,pr2)))
+ | No(Imp(f1,f2)) ->
+ let sq1 = sq11@(substract sq21 [f2])
+ and sq2 = (substract sq12 [f1])@sq22
+ in (Proof2(Imp(f1,f2)::sq1,sq2,LImp2(f1,pr1,f2,pr2)))
+ | _ -> failwith "Not a conjunction in conj_case !"
+ )
+
+let rec rneg_case pr = function
+ ((Po(Neg f))::lng) ->
+ let ((Proof2(sq1,sq2,_)) as pr1) = rneg_case pr lng
+ in let sq1' = substract sq1 [f]
+ and sq2' = (Neg f)::sq2
+ in (Proof2(sq1',sq2',RNeg2(f,pr1)))
+ | [] -> pr
+
+let lneg_case ((Proof2(sq1,sq2,_)) as pr) (No(Neg f)) =
+ let sq1' = (Neg f)::sq1
+ and sq2' = substract sq2 [f]
+ in (Proof2(sq1',sq2',LNeg2(f,pr)))
+
+let find_lneg lneg =
+ let rec is_negneg = function
+ t::ll -> (match t with
+ No(Neg(Neg(f))) -> t
+ | _ -> is_negneg ll
+ )
+ | [] -> raise Not_found
+ in try is_negneg lneg
+ with Not_found -> List.hd lneg
+
+let rec proof_of_path sT p =
+ let (ns,disj,at,nat,conj,rneg,lneg) = decomp sT p
+ in let sT1 = substract sT ns
+ in let pr1 = if disj=[]
+ then cases (at,nat,conj,rneg,lneg) p
+ else disj_case disj sT1 p
+ in apply_weakening pr1 ns
+and disj_case disj sT1 p =
+ let rec disj_case_rec s = function
+ d::ld -> let (a,b) = one_disj_comp d
+ in let nsatA = (not ((sat p a)))
+ and nsatB = (not ((sat p b)))
+ in let s1 = substract s [d]
+ in let s2 = if nsatA then b::s1
+ else if nsatB then a::s1
+ else a::(b::s1)
+ in let pr = disj_case_rec s2 ld
+ in let pr1 = if nsatA then apply_weakening pr [a]
+ else if nsatB then apply_weakening pr [b]
+ else pr
+ in apply_one_disj pr1 d
+ | [] -> proof_of_path s p
+ in disj_case_rec sT1 disj
+and cases (at,nat,conj,rneg,lneg) p =
+ try let (a,b) = find_axiom (at,nat) p
+ in let pr = (Proof2([b],[a],Axiom2(a)))
+ in let wk = (substract at [(Po a)])
+ @(substract nat [(No b)])
+ @conj@rneg@lneg
+ in apply_weakening pr wk
+ with Not_found ->
+ if conj<>[] then
+ let (x0,(s1,p1),(s2,p2)) = sep_path (at,nat,conj,rneg,lneg) p
+ in let pr1 = proof_of_path s1 p1
+ in let pr2 = proof_of_path s2 p2
+ in let pr = conj_case x0 pr1 pr2
+ in rneg_case pr rneg
+ else
+ if rneg<>[] then
+ let s = at@nat@lneg@(List.map (fun (Po (Neg f)) -> (No f)) rneg)
+ in let pr = proof_of_path s p
+ in rneg_case pr rneg
+ else
+ let (No (Neg f)) as g = find_lneg lneg
+ in let s = at@nat@(substract lneg [g])@[Po f]
+ in let pr = proof_of_path s p
+ in lneg_case pr g
+
+
+(* pi_formula : separated formula -> formula
+ pi_proof : separated proof -> proof *******)
+
+let rec pi_formula = function
+ Atom((s,_),lt) -> Atom((s,0),lt)
+ | Neg(f) -> Neg(pi_formula f)
+ | Imp(f1,f2) -> Imp(pi_formula f1,pi_formula f2)
+ | Conj(f1,f2) -> Conj(pi_formula f1,pi_formula f2)
+ | Disj(f1,f2) -> Disj(pi_formula f1,pi_formula f2)
+ | ForAll(s,f) -> ForAll(s,pi_formula f)
+ | Exists(s,f) -> Exists(s,pi_formula f)
+
+let rec pi_proof (Proof2(sq1,sq2,rule)) =
+ let sq1' = List.map pi_formula sq1
+ and sq2' = List.map pi_formula sq2
+ in let rule1 = match rule with
+ Axiom2(f) -> Axiom2(pi_formula f)
+ | RWeakening2(f,p) -> RWeakening2(pi_formula f,pi_proof p)
+ | LWeakening2(f,p) -> LWeakening2(pi_formula f,pi_proof p)
+ | RNeg2(f,p) -> RNeg2(pi_formula f,pi_proof p)
+ | LNeg2(f,p) -> LNeg2(pi_formula f,pi_proof p)
+ | RConj2(f1,p1,f2,p2)
+ -> RConj2(pi_formula f1,pi_proof p1,pi_formula f2,pi_proof p2)
+ | LDisj2(f1,p1,f2,p2)
+ -> LDisj2(pi_formula f1,pi_proof p1,pi_formula f2,pi_proof p2)
+ | LImp2(f1,p1,f2,p2)
+ -> LImp2(pi_formula f1,pi_proof p1,pi_formula f2,pi_proof p2)
+ | LConj2(f1,f2,p) -> LConj2(pi_formula f1,pi_formula f2,pi_proof p)
+ | RDisj2(f1,f2,p) -> RDisj2(pi_formula f1,pi_formula f2,pi_proof p)
+ | RImp2(f1,f2,p) -> RImp2(pi_formula f1,pi_formula f2,pi_proof p)
+ | RForAll2(s,f,p) -> RForAll2(s,pi_formula f,pi_proof p)
+ | LExists2(s,f,p) -> LExists2(s,pi_formula f,pi_proof p)
+ | LForAll2(s,t,f,p) -> LForAll2(s,t,pi_formula f,pi_proof p)
+ | RExists2(s,t,f,p) -> RExists2(s,t,pi_formula f,pi_proof p)
+ in (Proof2(sq1',sq2',rule1))
+
+(*** Introduction of quantifiers in proof ******)
+
+type quantifier = Universal of identifier * formula * bool
+ | Existential of identifier * formula * bool
+
+
+let her v ex =
+ let lt = List.map (fun x-> VAR(x)) ex
+ in (v,APP (GLOB (SK v)::lt))
+
+(*** quant_var returns all the quantifiers of a formula *****)
+
+let quant_var f =
+ let rec qv_rec sign = function
+ ForAll(v,f) -> let qt = qv_rec sign f in
+ if sign then (Universal(v,f,true))::qt
+ else (Existential(v,f,false))::qt
+ | Exists(v,f) -> let qt = qv_rec sign f in
+ if sign then (Existential(v,f,true))::qt
+ else (Universal(v,f,false))::qt
+ | Atom(_) -> []
+ | Neg(f) -> qv_rec ((not (sign))) f
+ | Imp(f1,f2) -> let qt1 = qv_rec ((not (sign))) f1
+ and qt2 = qv_rec sign f2
+ in qt1@qt2
+ | Conj(f1,f2) -> let qt1 = qv_rec sign f1
+ and qt2 = qv_rec sign f2
+ in qt1@qt2
+ | Disj(f1,f2) -> let qt1 = qv_rec sign f1
+ and qt2 = qv_rec sign f2
+ in qt1@qt2
+ in qv_rec true f
+
+(*** replace the skolem functions by their corresponding variables ****)
+
+let rec unher_term lv = function
+ | APP (GLOB (SK v)::_) -> VAR v
+ | APP lt -> APP (unher_list_term lv lt)
+ | x -> x
+and unher_list_term lv lt =
+ List.map (unher_term lv) lt
+
+let rec unher_unif lv = function
+ ((x,t)::ll) -> (x,unher_term lv t)::(unher_unif lv ll)
+ | [] -> []
+
+let rec unher_formula lv = function
+ Atom(s,lt) -> Atom(s,unher_list_term lv lt)
+ | Neg(f) -> Neg(unher_formula lv f)
+ | Imp(f1,f2) -> Imp(unher_formula lv f1,unher_formula lv f2)
+ | Conj(f1,f2) -> Conj(unher_formula lv f1,unher_formula lv f2)
+ | Disj(f1,f2) -> Disj(unher_formula lv f1,unher_formula lv f2)
+ | ForAll(s,f) -> ForAll(s,unher_formula lv f)
+ | Exists(s,f) -> Exists(s,unher_formula lv f)
+
+let rec unher_sequent lv = function
+ (f::ll) -> (unher_formula lv f)::(unher_sequent lv ll)
+ | [] -> []
+
+let rec unher_proof lv (Proof2(sq1,sq2,rule)) =
+ let sq1' = unher_sequent lv sq1
+ and sq2' = unher_sequent lv sq2
+ in let rule1 = match rule with
+ Axiom2(f) -> Axiom2(unher_formula lv f)
+ | RWeakening2(f,p) -> RWeakening2(unher_formula lv f,unher_proof lv p)
+ | LWeakening2(f,p) -> LWeakening2(unher_formula lv f,unher_proof lv p)
+ | RNeg2(f,p) -> RNeg2(unher_formula lv f,unher_proof lv p)
+ | LNeg2(f,p) -> LNeg2(unher_formula lv f,unher_proof lv p)
+ | RConj2(f1,p1,f2,p2) -> RConj2(unher_formula lv f1,unher_proof lv p1,
+ unher_formula lv f2,unher_proof lv p2)
+ | LDisj2(f1,p1,f2,p2) -> LDisj2(unher_formula lv f1,unher_proof lv p1,
+ unher_formula lv f2,unher_proof lv p2)
+ | LImp2(f1,p1,f2,p2) -> LImp2(unher_formula lv f1,unher_proof lv p1,
+ unher_formula lv f2,unher_proof lv p2)
+ | LConj2(f1,f2,p) -> LConj2(unher_formula lv f1,unher_formula lv f2,
+ unher_proof lv p)
+ | RDisj2(f1,f2,p) -> RDisj2(unher_formula lv f1,unher_formula lv f2,
+ unher_proof lv p)
+ | RImp2(f1,f2,p) -> RImp2(unher_formula lv f1,unher_formula lv f2,
+ unher_proof lv p)
+ | RForAll2(s,f,p) -> RForAll2(s,unher_formula lv f,unher_proof lv p)
+ | LExists2(s,f,p) -> LExists2(s,unher_formula lv f,unher_proof lv p)
+ | LForAll2(s,t,f,p) -> LForAll2(s,t,unher_formula lv f,unher_proof lv p)
+ | RExists2(s,t,f,p) -> RExists2(s,t,unher_formula lv f,unher_proof lv p)
+ in (Proof2(sq1',sq2',rule1))
+
+(*** subst_f_qt : quantifier_list -> formula -> formula *****)
+
+let subst_f_qt sqt f =
+ let rec sub_rec f0 = function
+ q::ll -> let f1 = sub_rec f0 ll in
+ (match q with
+ Universal(id,f_0,t) -> let f' = if t then ForAll(id,f_0)
+ else Exists(id,f_0)
+ in subst_f_f f_0 f' f1
+ | Existential(id,f_0,t) -> let f' = if t then Exists(id,f_0)
+ else ForAll(id,f_0)
+ in subst_f_f f_0 f' f1
+ )
+ | [] -> f0
+ in sub_rec f sqt
+
+
+let quant_in id f =
+ let rec qi = function
+ Atom(_) -> false
+ | Neg(f1) -> qi f1
+ | Conj(f1,f2) -> (qi f1) or (qi f2)
+ | Disj(f1,f2) -> (qi f1) or (qi f2)
+ | Imp(f1,f2) -> (qi f1) or (qi f2)
+ | ForAll(id',f1) -> if id=id' then true else qi f1
+ | Exists(id',f1) -> if id=id' then true else qi f1
+ in qi f
+
+
+let weak_quant f =
+ let rec wq_rec = function
+ ((Universal(id,_,_)) as q)::ll -> if quant_in id f then q::(wq_rec ll)
+ else wq_rec ll
+ | ((Existential(id,_,_)) as q)::ll -> if quant_in id f then q::(wq_rec ll)
+ else wq_rec ll
+ | [] -> []
+ in wq_rec
+
+
+let proof_quant (Proof2(sq1,sq2,_)) sqt =
+ let sq = List.map (subst_f_qt sqt)(sq1@sq2)
+ in
+ let id_in_sq id =
+ List.fold_left (fun r f -> if r then true else (id_in_formula id f)) false sq
+ in
+ let rec pq_rec = function
+ ((Universal(id,_,_)) as q)::ll -> if id_in_sq id then q::(pq_rec ll)
+ else pq_rec ll
+ | ((Existential(id,_,_)) as q)::ll -> if id_in_sq id then q::(pq_rec ll)
+ else pq_rec ll
+ | [] -> []
+ in pq_rec sqt
+
+
+let find_quant pog sq1' sq2' =
+ let appear = function
+ (Universal(id,f,t))
+ -> let qf = if t then ForAll(id,f) else Exists(id,f)
+ in (List.mem qf sq1') or (List.mem qf sq2')
+ | (Existential(id,f,t))
+ -> let qf = if t then Exists(id,f) else ForAll(id,f)
+ in (List.mem qf sq1') or (List.mem qf sq2')
+ in
+ let rec find_rec = function
+ (q,r)::l -> if !r=0 then if appear q then q
+ else find_rec l
+ else find_rec l
+ | [] -> raise Not_found
+ in find_rec pog
+
+
+(*** make_pog : make partial order graph
+ make_pog : quantifier list -> (quantifier * quantifier) list
+ -> (quantifier * int ref) list *******)
+
+let make_pog qt cst =
+ let pog0 = List.map (fun x -> (x,ref 0)) qt
+ in
+ let rec make_rec = function
+ (q,q')::l -> if (List.mem q qt) & (List.mem q' qt) then
+ let r = List.assoc q' pog0 in r := !r + 1
+ else () ;
+ make_rec l
+ | [] -> pog0
+ in
+ make_rec cst
+
+
+let update_pog cst pog lq =
+ let remove_one q0 =
+ let rec rm_rec = function
+ (q,r)::ll -> if q=q0
+ then rm_rec ll
+ else if List.mem (q0,q) cst
+ then begin r := !r - 1; (q,r)::(rm_rec ll) end
+ else (q,r)::(rm_rec ll)
+ | [] -> []
+ in rm_rec
+ in
+ let rec remove_all pog0 = function
+ q::ll -> let pog1 = remove_one q pog0 in
+ remove_all pog1 ll
+ | [] -> pog0
+ in
+ remove_all pog lq
+
+
+(*** sort_pog : pog -> quantifier list *****)
+
+let sort_pog cst pog =
+ let pog' = List.map (fun (x,r) -> (x,ref (!r))) pog
+ in
+ let decrease_one x =
+ let rec dec_rec = function
+ (q,q')::ll -> if (q=x) & (List.mem_assoc q' pog')
+ then begin
+ let r = List.assoc q' pog' in
+ r := !r - 1; dec_rec ll
+ end
+ else dec_rec ll
+ | [] -> ()
+ in dec_rec cst
+ in
+ let rec decrease = function
+ x::ll -> decrease_one x; decrease ll
+ | [] -> ()
+ in
+ let rec find_min = function
+ (x,r)::ll -> if !r=0
+ then begin r := -1; x::(find_min ll) end
+ else find_min ll
+ | [] -> []
+ in
+ let rec loop od =
+ let m = find_min pog' in
+ if m=[] then od
+ else begin decrease m; loop (od@m) end
+ in loop []
+
+
+(*** quant_proof : cst -> pog -> lkproof2 -> lkproof2 ********)
+
+let rec quant_proof cst pog ((Proof2(sq1,sq2,rule)) as pr) =
+ if pog=[] then pr
+ else
+ let sqt = sort_pog cst pog in
+ let sq1' = List.map (subst_f_qt sqt) sq1
+ and sq2' = List.map (subst_f_qt sqt) sq2
+ in
+ let rule' = match rule with
+ LWeakening2(f,p) -> let f' = subst_f_qt sqt f in
+ let wq = weak_quant f' sqt in
+ LWeakening2(f',quant_proof cst (update_pog cst pog wq) p)
+ | RWeakening2(f,p) -> let f' = subst_f_qt sqt f in
+ let wq = weak_quant f' sqt in
+ RWeakening2(f',quant_proof cst (update_pog cst pog wq) p)
+ | _ -> (try
+ let q1 = find_quant pog sq1' sq2' in
+ let pr' = quant_proof cst (update_pog cst pog [q1]) pr in
+ (match q1 with
+ Universal(id,f,t) -> if t then RForAll2(id,f,pr')
+ else LExists2(id,f,pr')
+ | Existential(id,f,t) -> if t then RExists2(id,VAR id,f,pr')
+ else LForAll2(id,VAR id,f,pr') )
+ with Not_found ->
+ (match rule with
+ Axiom2(f) -> Axiom2(f)
+ | RNeg2(f,p) -> RNeg2(subst_f_qt sqt f,quant_proof cst pog p)
+ | LNeg2(f,p) -> LNeg2(subst_f_qt sqt f,quant_proof cst pog p)
+ | RConj2(f1,p1,f2,p2)
+ -> let sqt1 = proof_quant p1 sqt in
+ let pog1 = make_pog sqt1 cst in
+ let pog2 = make_pog (substract sqt sqt1) cst in
+ RConj2(subst_f_qt sqt f1,quant_proof cst pog1 p1,
+ subst_f_qt sqt f2,quant_proof cst pog2 p2)
+ | LConj2(f1,f2,p) -> LConj2(subst_f_qt sqt f1,subst_f_qt sqt f2,
+ quant_proof cst pog p)
+ | RDisj2(f1,f2,p) -> RDisj2(subst_f_qt sqt f1,subst_f_qt sqt f2,
+ quant_proof cst pog p)
+ | LDisj2(f1,p1,f2,p2)
+ -> let sqt1 = proof_quant p1 sqt in
+ let pog1 = make_pog sqt1 cst in
+ let pog2 = make_pog (substract sqt sqt1) cst in
+ LDisj2(subst_f_qt sqt f1,quant_proof cst pog1 p1,
+ subst_f_qt sqt f2,quant_proof cst pog2 p2)
+ | RImp2(f1,f2,p) -> RImp2(subst_f_qt sqt f1,subst_f_qt sqt f2,
+ quant_proof cst pog p)
+ | LImp2(f1,p1,f2,p2)
+ -> let sqt1 = proof_quant p1 sqt in
+ let pog1 = make_pog sqt1 cst in
+ let pog2 = make_pog (substract sqt sqt1) cst in
+ LImp2(subst_f_qt sqt f1,quant_proof cst pog1 p1,
+ subst_f_qt sqt f2,quant_proof cst pog2 p2)
+ | _ -> raise Impossible_case
+ ))
+ in (Proof2(sq1',sq2',rule'))
+
+
+(*** apply_unif_f : unifier -> formula -> formula *****)
+
+let apply_unif_f u =
+ let rec auf_rec = function
+ Atom(n,lt) -> Atom(n,List.map (apply_unif u) lt)
+ | Neg(f) -> Neg(auf_rec f)
+ | Conj(f1,f2) -> Conj(auf_rec f1,auf_rec f2)
+ | Disj(f1,f2) -> Disj(auf_rec f1,auf_rec f2)
+ | Imp(f1,f2) -> Imp(auf_rec f1,auf_rec f2)
+ | ForAll(id,f) -> ForAll(id,auf_rec f)
+ | Exists(id,f) -> Exists(id,auf_rec f)
+ in auf_rec
+
+
+(*** witness_proof : quantifier list -> unifier -> lkproof2 -> lkproof2 ****)
+
+let witness_proof u0 pr =
+ let rec wit_rec u (Proof2(sq1,sq2,rule)) =
+ let sq1' = List.map (apply_unif_f u) sq1
+ and sq2' = List.map (apply_unif_f u) sq2 in
+ let rule' = match rule with
+ Axiom2(f) -> Axiom2(apply_unif_f u f)
+ | RWeakening2(f,p) -> RWeakening2(apply_unif_f u f,wit_rec u p)
+ | LWeakening2(f,p) -> LWeakening2(apply_unif_f u f,wit_rec u p)
+ | RNeg2(f,p) -> RNeg2(apply_unif_f u f,wit_rec u p)
+ | LNeg2(f,p) -> LNeg2(apply_unif_f u f,wit_rec u p)
+ | RConj2(f1,p1,f2,p2) -> RConj2(apply_unif_f u f1,wit_rec u p1,
+ apply_unif_f u f2,wit_rec u p2)
+ | LConj2(f1,f2,p) -> LConj2(apply_unif_f u f1,apply_unif_f u f2,
+ wit_rec u p)
+ | RDisj2(f1,f2,p) -> RDisj2(apply_unif_f u f1,apply_unif_f u f2,
+ wit_rec u p)
+ | LDisj2(f1,p1,f2,p2) -> LDisj2(apply_unif_f u f1,wit_rec u p1,
+ apply_unif_f u f2,wit_rec u p2)
+ | RImp2(f1,f2,p) -> RImp2(apply_unif_f u f1,apply_unif_f u f2,
+ wit_rec u p)
+ | LImp2(f1,p1,f2,p2) -> LImp2(apply_unif_f u f1,wit_rec u p1,
+ apply_unif_f u f2,wit_rec u p2)
+ | RForAll2(id,f,p) -> RForAll2(id,apply_unif_f u f,wit_rec u p)
+ | LForAll2(id,_,f,p) -> let f' = apply_unif_f u f in
+ let t = assoc_unif (VAR id) u0 in
+ LForAll2(id,t,f',wit_rec ((VAR id,t)::u) p)
+ | RExists2(id,_,f,p) -> let f' = apply_unif_f u f in
+ let t = assoc_unif (VAR id) u0 in
+ RExists2(id,t,f',wit_rec ((VAR id,t)::u) p)
+ | LExists2(id,f,p) -> LExists2(id,apply_unif_f u f,wit_rec u p)
+ in (Proof2(sq1',sq2',rule'))
+ in wit_rec [] pr
+
+
+(*** make constraints on quantifiers ******)
+(*** make_constraints :
+ quantifier list -> unifier -> (quantifier * quantifier) list ***)
+
+let in_witness id t =
+ let vt = all_var_term t
+ in List.mem id vt
+
+
+let before u = fun
+ p_0 p_1 -> match p_0,p_1 with ((Universal(id,f,_)), (Universal(id',f',_)))
+ -> if id=id' then false
+ else quant_in id' f
+ | ((Universal(id,f,_)), (Existential(id',f',_)))
+ -> (quant_in id' f) or (in_witness id (assoc_unif (VAR id') u))
+ | ((Existential(id,f,_)), (Universal(id',f',_)))
+ -> quant_in id' f
+ | ((Existential(id,f,_)), (Existential(id',f',_)))
+ -> if id=id' then false
+ else (quant_in id' f) or (in_witness id (assoc_unif (VAR id') u))
+
+
+let make_constraints qt u =
+ let rec goods = function
+ (a,b)::ll -> if before u a b
+ then (a,b)::(goods ll)
+ else goods ll
+ | [] -> []
+ in
+ let all = glue (List.map (fun a -> (List.map (fun b -> (a,b)) qt)) qt)
+ in
+ goods all
+
+
+
+(*** Introduce all the quantifiers in a proof (one after each other,
+ using apply_ex and apply_un) ********)
+
+let int_quant f u pr =
+ let qt = quant_var f
+ in let un_qt = such_that qt (function (Universal _) -> true | _ -> false)
+ and fr_var = free_var_formula f
+ in let un_var = List.map (fun (Universal(id,_,_)) -> id) un_qt
+ in let sk_var = un_var @ fr_var
+ in let u0 = unher_unif sk_var u
+ in let pr0 = pi_proof pr
+ in let pr1 = unher_proof sk_var pr0
+ in let cst = make_constraints qt u0
+ in let pog = make_pog qt cst
+ in let qpr = quant_proof cst pog pr1
+ in witness_proof u0 qpr
+
diff --git a/contrib/linear/prove.ml b/contrib/linear/prove.ml
new file mode 100755
index 0000000000..35c3f3427b
--- /dev/null
+++ b/contrib/linear/prove.ml
@@ -0,0 +1,80 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $Id$ i*)
+
+open Dpctypes;;
+open Kwc;;
+open Lk_proofs;;
+
+exception Not_provable_in_DPC of string
+;;
+exception No_intuitionnistic_proof of int
+;;
+
+(* is_int_proof : lkproof2 -> bool *******)
+
+let rec is_int_proof (Proof2(sq1,sq2,rule)) =
+ if (List.length sq2)>1 then false
+ else match rule with
+ Axiom2(_) -> true
+ | RWeakening2(_,p) -> is_int_proof p
+ | LWeakening2(_,p) -> is_int_proof p
+ | RNeg2(_,p) -> is_int_proof p
+ | LNeg2(_,p) -> is_int_proof p
+ | RConj2(_,p1,_,p2) -> (is_int_proof p1) & (is_int_proof p2)
+ | LConj2(_,_,p) -> is_int_proof p
+ | RDisj2(f1,f2,Proof2(_,_,RWeakening2(f3,p))) ->
+ if (f3=f1) or (f3=f2) then is_int_proof p
+ else false
+ | RDisj2(_,_,_) -> false
+ | LDisj2(_,p1,_,p2) -> (is_int_proof p1) & (is_int_proof p2)
+ | RImp2(_,_,p) -> is_int_proof p
+ | LImp2(_,p1,_,p2) -> (is_int_proof p1) & (is_int_proof p2)
+ | RForAll2(_,_,p) -> is_int_proof p
+ | LForAll2(_,_,_,p) -> is_int_proof p
+ | RExists2(_,_,_,p) -> is_int_proof p
+ | LExists2(_,_,p) -> is_int_proof p
+;;
+
+(* find_int_proof : f -> f1 -> path list -> lkproof2 *****)
+
+let find_int_proof f f1 all_v_paths =
+ let rec find_rec = function
+ p::ll -> let pr0 = proof_of_path [Po(f1)] p in
+ if is_int_proof pr0
+ then int_quant f (snd p) pr0
+ else find_rec ll
+ | [] -> raise Not_found
+ in find_rec all_v_paths
+;;
+
+(* prove_f : formula -> lk_proof2
+ prove : string -> lk_proof2 *******)
+
+let prove_f f =
+ let f0 = separate f
+ in let (ex,f1) = herbrand f0
+ in let (pos,neg,lcj) = lit_conj f1
+ in let cj = List.map (fun (c,_) -> c) lcj
+ in let m = all_matches pos neg lcj
+ in if m = []
+ then raise (Not_provable_in_DPC "(No match)")
+
+ else let all_paths = paths pos neg m lcj
+ in if all_paths = []
+ then raise (Not_provable_in_DPC "(No path)")
+
+ else let all_valid_paths = good_paths lcj all_paths
+ in if all_valid_paths = []
+ then raise (Not_provable_in_DPC "(No valid path)")
+
+ else try find_int_proof f f1 all_valid_paths
+ with Not_found -> let n = List.length all_valid_paths
+ in raise (No_intuitionnistic_proof n)
+;;
diff --git a/contrib/linear/prove.mli b/contrib/linear/prove.mli
new file mode 100755
index 0000000000..67381b438a
--- /dev/null
+++ b/contrib/linear/prove.mli
@@ -0,0 +1,19 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $Id$ i*)
+
+open Dpctypes;;
+
+exception Not_provable_in_DPC of string
+;;
+exception No_intuitionnistic_proof of int
+;;
+
+val prove_f : formula -> lkproof2;;
+
diff --git a/contrib/linear/subst.ml b/contrib/linear/subst.ml
new file mode 100755
index 0000000000..8e16565d7a
--- /dev/null
+++ b/contrib/linear/subst.ml
@@ -0,0 +1,150 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $Id$ i*)
+
+open General
+open Names
+open Dpctypes
+
+(* subst_term : identifier -> term -> term -> term
+ subst_list_term : identifier -> term -> term list -> term list *****)
+
+let rec subst_term v t = function
+ VAR(s) -> if s=v then t else (VAR s)
+ | GLOB _ as x -> x
+ | APP(lt) -> APP(subst_list_term v t lt)
+and subst_list_term v t = function
+ t1::l1 -> (subst_term v t t1)::(subst_list_term v t l1)
+| [] -> []
+
+(* subst : identifier -> term -> formula -> formula *)
+
+let subst v t =
+ let rec subst_rec f = match f with
+ Atom(s,lt) -> Atom(s,subst_list_term v t lt)
+ | Neg(f1) -> Neg(subst_rec f1)
+ | Imp(f1,f2) -> Imp(subst_rec f1,subst_rec f2)
+ | Conj(f1,f2) -> Conj(subst_rec f1, subst_rec f2)
+ | Disj(f1,f2) -> Disj(subst_rec f1, subst_rec f2)
+ | ForAll(s,f1) -> ForAll(s,subst_rec f1)
+ | Exists(s,f1) -> Exists(s, subst_rec f1)
+ in subst_rec
+
+(* all_lit : formula -> formula list *)
+
+let rec all_lit = function
+ Atom((x_0,x_1)) -> [Atom((x_0,x_1))]
+ | Neg(f) -> all_lit f
+ | Conj(f1,f2) -> (all_lit f1)@(all_lit f2)
+ | Disj(f1,f2) -> (all_lit f1)@(all_lit f2)
+ | Imp(f1,f2) -> (all_lit f1)@(all_lit f2)
+ | _ -> raise Impossible_case
+
+(* occurs : formula -> formula -> bool *)
+
+let occurs s =
+ let rec occurs_rec f = if s=f then true else match f with
+ Neg(f1) -> (occurs_rec f1)
+ | ForAll(s,f1) -> (occurs_rec f1)
+ | Exists(s,f1) -> (occurs_rec f1)
+ | Imp(f1,f2) -> (occurs_rec f1) or (occurs_rec f2)
+ | Conj(f1,f2) -> (occurs_rec f1) or (occurs_rec f2)
+ | Disj(f1,f2) -> (occurs_rec f1) or (occurs_rec f2)
+ | _ -> false
+ in occurs_rec
+
+(* subst_f_f : formula -> formula -> formula -> formula *)
+
+let rec subst_f_f fa fb f =
+ if f=fa
+ then fb
+ else match f with
+ Atom(_,_) as a -> a
+ | Neg(f1) -> Neg(subst_f_f fa fb f1)
+ | Conj(f1,f2) -> Conj(subst_f_f fa fb f1,subst_f_f fa fb f2)
+ | Disj(f1,f2) -> Disj(subst_f_f fa fb f1,subst_f_f fa fb f2)
+ | Imp(f1,f2) -> Imp(subst_f_f fa fb f1,subst_f_f fa fb f2)
+ | ForAll(s,f1) -> ForAll(s,subst_f_f fa fb f1)
+ | Exists(s,f1) -> Exists(s,subst_f_f fa fb f1)
+
+(* subst_proof2 : identifier -> term -> lkproof2 -> lkproof2 *)
+
+let rec subst_proof2 v t (Proof2(sq1,sq2,rule)) =
+ let sq1' = List.map (subst v t) sq1
+ and sq2' = List.map (subst v t) sq2
+ in let rule1 = match rule with
+ Axiom2(f) -> Axiom2(subst v t f)
+ | RWeakening2(f,p) -> RWeakening2(subst v t f,subst_proof2 v t p)
+ | LWeakening2(f,p) -> LWeakening2(subst v t f,subst_proof2 v t p)
+ | RNeg2(f,p) -> RNeg2(subst v t f,subst_proof2 v t p)
+ | LNeg2(f,p) -> LNeg2(subst v t f,subst_proof2 v t p)
+ | RConj2(f1,p1,f2,p2) -> RConj2(subst v t f1,subst_proof2 v t p1,
+ subst v t f2,subst_proof2 v t p2)
+ | LDisj2(f1,p1,f2,p2) -> LDisj2(subst v t f1,subst_proof2 v t p1,
+ subst v t f2,subst_proof2 v t p2)
+ | LImp2(f1,p1,f2,p2) -> LImp2(subst v t f1,subst_proof2 v t p1,
+ subst v t f2,subst_proof2 v t p2)
+ | LConj2(f1,f2,p) -> LConj2(subst v t f1,subst v t f2,
+ subst_proof2 v t p)
+ | RDisj2(f1,f2,p) -> RDisj2(subst v t f1,subst v t f2,
+ subst_proof2 v t p)
+ | RImp2(f1,f2,p) -> RImp2(subst v t f1,subst v t f2,
+ subst_proof2 v t p)
+ | RForAll2(s,f,p) -> RForAll2(s,subst v t f,subst_proof2 v t p)
+ | LExists2(s,f,p) -> LExists2(s,subst v t f,subst_proof2 v t p)
+ | LForAll2(s,t1,f,p) -> LForAll2(s,subst_term v t t1,
+ subst v t f,subst_proof2 v t p)
+ | RExists2(s,t1,f,p) -> RExists2(s,subst_term v t t1,
+ subst v t f,subst_proof2 v t p)
+ in (Proof2(sq1',sq2',rule1))
+
+(* All the free variables of a formula... ******)
+
+let rec all_var_term = function
+ VAR s -> [s]
+ | GLOB _ -> []
+ | APP lt -> all_var_list_term lt
+and all_var_list_term = function
+ t::ll -> union (all_var_term t) (all_var_list_term ll)
+ | [] -> []
+
+(* free_var_formula : formula -> identifier list ******)
+
+let rec free_var_formula = function
+ Atom(s,lt) -> all_var_list_term lt
+ | Neg(f) -> free_var_formula f
+ | Imp(f1,f2) -> union (free_var_formula f1) (free_var_formula f2)
+ | Conj(f1,f2) -> union (free_var_formula f1) (free_var_formula f2)
+ | Disj(f1,f2) -> union (free_var_formula f1) (free_var_formula f2)
+ | ForAll(s,f) -> substract (free_var_formula f) [s]
+ | Exists(s,f) -> substract (free_var_formula f) [s]
+
+(*** id_in_term : identifier -> term -> bool
+ id_in_list : identifier -> term list -> bool ****)
+
+let rec id_in_term id = function
+ VAR id' -> id=id'
+ | GLOB _ -> false
+ | APP lt -> id_in_list id lt
+and id_in_list id =
+ List.fold_left (fun r t -> if r then true else id_in_term id t) false
+
+
+(*** id_in_formula : identifier -> formula -> bool ****)
+
+let rec id_in_formula id = function
+ Atom(_,lt) -> id_in_list id lt
+ | Neg(f) -> id_in_formula id f
+ | Conj(f1,f2) -> (id_in_formula id f1) or (id_in_formula id f2)
+ | Disj(f1,f2) -> (id_in_formula id f1) or (id_in_formula id f2)
+ | Imp(f1,f2) -> (id_in_formula id f1) or (id_in_formula id f2)
+ | ForAll(id',f) -> (id=id') or (id_in_formula id f)
+ | Exists(id',f) -> (id=id') or (id_in_formula id f)
+
+
diff --git a/contrib/linear/subst.mli b/contrib/linear/subst.mli
new file mode 100755
index 0000000000..907d4d4192
--- /dev/null
+++ b/contrib/linear/subst.mli
@@ -0,0 +1,21 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $Id$ i*)
+
+open Dpctypes
+open Names
+
+val subst_term : identifier -> term -> term -> term
+val subst : identifier -> term -> formula -> formula
+val all_lit : formula -> formula list
+val subst_f_f : formula -> formula -> formula -> formula
+val all_var_term : term -> identifier list
+val free_var_formula : formula -> identifier list
+val id_in_formula : identifier -> formula -> bool
+
diff --git a/contrib/linear/unif.ml b/contrib/linear/unif.ml
new file mode 100755
index 0000000000..8cf2b0b7d4
--- /dev/null
+++ b/contrib/linear/unif.ml
@@ -0,0 +1,311 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $Id$ i*)
+
+ (* UNIFICATION : Martelli & Montanari's algorithm *)
+ (* ---------------------------------------------- *)
+
+(* Terms are of the type :
+ * type term = Var of identifier
+ * | Glob of constname
+ * | App of term list
+ *
+ * Unification of two atomic formulae :
+ * unif_atoms : atom_id * term list -> atom_id * term list
+ * -> (term*term) list
+ *
+ * Unification of two terms :
+ * unif_terms : term -> term -> (term*term) list
+ *
+ *)
+
+open Nameops
+open General
+open Dpctypes
+open Subst
+
+exception Not_unifiable
+exception Up_error
+
+let rec vars_of_list l = match l with
+ t::ll -> let vll = vars_of_list ll
+ in let vt = vars_of_term t
+ in union vt vll
+ | [] -> []
+and vars_of_term t = match t with
+ VAR x -> [VAR(x)]
+ | GLOB _ -> []
+ | APP lt -> vars_of_list lt
+
+let rec nb_occ_term x t = match t with
+ VAR y -> if x=VAR(y) then 1 else 0
+ | APP lt -> nb_occ_list x lt
+ | _ -> 0
+and nb_occ_list x l = match l with
+ t::ll -> (nb_occ_term x t)+(nb_occ_list x ll)
+ | [] -> 0
+
+let cpt = ref 0
+
+let w_atom = "-"
+
+let new_id () =
+ cpt := !cpt+1;
+ make_ident w_atom (Some !cpt)
+
+let rec initU l1 l2 = match (l1,l2) with
+ ((a1::ll1),(a2::ll2)) -> let w = new_id()
+ in let equ = ([VAR w],[a1; a2])
+ in equ::(initU ll1 ll2)
+ | ([],[]) -> []
+ | _ -> raise Impossible_case
+
+let initT l1 l2 =
+ let lt =l1@l2
+ in List.map (fun x -> ([x],[])) (vars_of_list lt)
+
+let rec cF (t1,t2) = match t1 with
+ VAR(x1) ->
+ (match t2 with
+ VAR _ -> ([t1] , [([t1; t2],[])])
+ | _ -> ([] , [([t1],[t2])])
+ )
+ | GLOB _ -> (match t2 with
+ GLOB _ -> if t1=t2 then ([t1] , []) else raise Not_unifiable
+ | VAR _ -> ([] , [([t2],[t1])])
+ | _ -> raise Not_unifiable)
+ | APP lt1 ->
+ (match t2 with
+ VAR _ -> ([] , [([t2],[t1])])
+ | GLOB _ -> raise Not_unifiable
+ | APP lt2 ->
+ if (List.length lt1)=(List.length lt2)
+ then let lcf = List.map cF (List.combine lt1 lt2)
+ in let lc = List.map (function ([x],_) -> x
+ | ([],e) -> List.hd (fst (List.hd e))
+ | _ -> failwith "Imp.CF") lcf
+ in let llf = List.map (fun (_,x) -> x) lcf
+ in ([APP lc] , glue llf)
+ else raise Not_unifiable
+ )
+
+let assocT x t =
+ let rec assocT_rec = function
+ ((lv , _) as equ::tT) -> if List.mem x lv then equ
+ else assocT_rec tT
+ | [] -> raise Not_found
+ in assocT_rec t
+
+let rec sub_elem_list x = function
+ (a::l) -> if a=x then l else a::(sub_elem_list x l)
+ | [] -> []
+
+let newUT1 x1 x2 u t =
+ let (lv1,lt1) as equ1 = assocT x1 t
+ in let (lv2,lt2) as equ2 = assocT x2 t
+ in let nT = sub_elem_list equ1 (sub_elem_list equ2 t)
+ in if equ1=equ2
+ then (u , t)
+ else if lt1=[] or lt2=[]
+ then (u , (lv1@lv2 , lt1@lt2)::nT)
+ else let t1 = List.hd lt1 and t2 = List.hd lt2
+ in let (c,f) = cF (t1,t2)
+ in (f@u , (lv1@lv2 , c)::nT)
+
+let newUT2 x1 t1 u t =
+ let (lv1,lt1) as equ1 = assocT x1 t
+ in let nT = sub_elem_list equ1 t
+ in match lt1 with
+ [t2] -> let (c,f) = cF (t1,t2)
+ in (f@u , (lv1 , c)::nT)
+ | [] -> (u , (lv1 , [t1])::nT)
+ | _ -> failwith "Imp.newUT2"
+
+let newUT3 w t1 t2 u t =
+ let (c,f) = cF (t1,t2)
+ in match t1 with
+ VAR(_) as x1 -> let (lv1,lt1) as equ1 = assocT x1 t
+ in let nT = sub_elem_list equ1 t
+ in let tT = (w::lv1,lt1)::nT
+ in (match t2 with
+ VAR(_) as x2 -> (([x1;x2],[])::u , tT)
+ | _ -> (([x1],[t2])::u , tT)
+ )
+ | _ -> (match t2 with
+ VAR(_) as x2 -> let (lv2,lt2) as equ2 = assocT x2 t
+ in let nT = sub_elem_list equ2 t
+ in let tT = (w::lv2,lt2)::nT
+ in (([x2],[t1])::u , tT)
+ | _ -> let (c,f) = cF (t1,t2)
+ in (f@u , ([w],c)::t)
+ )
+
+ (* mm : Compute the derivation of (U,T) until U=[] ***********)
+
+let rec mm u t = match u with
+ ((v,s)::uU) ->
+ (match s with
+ [] -> (match v with
+ [x1;x2] -> let (nU,nT) = newUT1 x1 x2 uU t
+ in mm nU nT
+ | _ -> failwith "Imp.cas 1"
+ )
+ | [t1] -> (match v with
+ [x1] -> let (nU,nT) = newUT2 x1 t1 uU t
+ in mm nU nT
+ | _ -> failwith "Imp.cas 2"
+ )
+ | [t1;t2] -> (match v with
+ [x1] -> let (nU,nT) = newUT3 x1 t1 t2 uU t
+ in mm nU nT
+ | _ -> failwith "Imp.cas 3"
+ )
+ | _ -> raise Impossible_case
+ )
+ | [] -> t
+
+
+let nb_occ_list_list lv ltt =
+ let rec nb_occ_ll_rec = function
+ (v::lv1) -> (nb_occ_list v ltt)+(nb_occ_ll_rec lv1)
+ | [] -> 0
+ in nb_occ_ll_rec lv
+
+let rec gro_aux = function
+ (VAR x)::ll -> if (atompart_of_id x) = w_atom then gro_aux ll
+ else (VAR x)::(gro_aux ll)
+ | h::ll -> h::(gro_aux ll)
+ | [] -> []
+
+let rec gro_aux_T = function
+ ((lv,lt)::tT) ->
+ let lv0 = gro_aux lv
+ in (match lv0 with
+ [] -> gro_aux_T tT
+ | _ -> (lv0,lt)::(gro_aux_T tT)
+ )
+ | [] -> []
+
+(* From now on, the equations of T are associated with the number of
+ occurences of their variables in the right equations *********)
+
+let rec find_null = function
+ ((r,(_,_)) as equ::tT) -> if !r=0 then equ else find_null tT
+ | [] -> raise Not_unifiable
+
+let rec recompute t1 t = match t1 with
+ ((r,(lv,lt))::tT) -> let n = nb_occ_list_list lv [t]
+ in (ref (!r-n),(lv,lt))::(recompute tT t)
+ | [] -> []
+
+let rec sorted_Tc t sT =
+ if t=[] then sT else
+ let (_,(lv,lt)) as equ = find_null t
+ in let t1 = sub_elem_list equ t
+ in match lt with
+ [] -> sorted_Tc t1 (equ::sT)
+ | [t_0] -> sorted_Tc (recompute t1 t_0) (equ::sT)
+ | _ -> raise Impossible_case
+
+let rec apply_subst s = function
+ VAR(_) as v -> if List.mem_assoc v s then List.assoc v s
+ else v
+ | GLOB _ as x -> x
+ | APP lt -> APP (List.map (apply_subst s) lt)
+
+let rec unif_from_sTc un = function
+ ((_,(lv,lt))::tT) ->
+ (match lt with
+ [] -> let x1 = List.hd lv and lv1 = List.tl lv
+ in let u0 = List.map (fun x->(x,x1)) lv1
+ in unif_from_sTc (un@u0) tT
+ | [t] -> let t0 = apply_subst un t
+ in let u0 = List.map (fun x->(x,t0)) lv
+ in unif_from_sTc (un@u0) tT
+ | _ -> raise Impossible_case
+ )
+ | [] -> un
+
+let unif_from_T t0 =
+ let t = gro_aux_T t0
+ in let llt = List.map (fun (_,x) -> x) t
+ in let ltt = glue llt
+ in let rec comp_nb t1 = match t1 with
+ ((lv,lt)::tT1) -> (ref (nb_occ_list_list lv ltt),(lv,lt))::
+ (comp_nb tT1)
+ | _ -> []
+ in let tc = comp_nb t
+ in let sTc = sorted_Tc tc []
+ in unif_from_sTc [] sTc
+
+(* unif_atoms : atom -> atom -> unifier ******)
+
+let unif_atoms (p1,l1) (p2,l2) =
+ if (fst p1)<>(fst p2) or (List.length l1)<>(List.length l2)
+ then raise Not_unifiable
+ else cpt := 0;
+ let t = mm (initU l1 l2) (initT l1 l2)
+ in unif_from_T t
+
+(* unif_terms : term -> term -> unifier *******)
+
+let unif_terms t1 t2 =
+ cpt := 0;
+ let l1 = [t1] and l2 =[t2]
+ in let t = mm (initU l1 l2) (initT l1 l2)
+ in unif_from_T t
+
+(* assoc_unif : unifier -> variable -> term ******)
+
+let assoc_unif v u =
+ try List.assoc v u
+ with Not_found -> v
+
+(* apply_unif : unifier -> term -> term ******)
+
+let apply_unif u t =
+ let rec au_rec = function
+ VAR _ as v -> assoc_unif v u
+ | GLOB _ as x -> x
+ | APP lt -> APP (List.map au_rec lt)
+ in au_rec t
+
+(* appear_var_term : variable -> term -> bool ********)
+
+let appear_var_term v t =
+ let rec avt_rec = function
+ VAR _ as v1 -> v1=v
+ | GLOB _ -> false
+ | APP lt -> List.fold_left (fun x t1 -> x or (avt_rec t1)) false lt
+ in avt_rec t
+
+(* up u1 u2 : returns the least unifier greater than u1 and u2
+ If no such unifier exists, it raises Up_error *******)
+
+let rec up u1 u2 = match u2 with
+ (((VAR s1) as y1,t1) as eq::uu2) ->
+ if List.mem_assoc y1 u1
+ then let m1 = List.assoc y1 u1
+ in let t1' = apply_unif u1 t1
+ in let u0 = try unif_terms m1 t1'
+ with Not_unifiable -> raise Up_error
+ in let u1' = List.map (fun (x,t) -> (x,apply_unif u0 t)) u1
+ in up (u1'@u0) uu2
+ else let t1' = apply_unif u1 t1
+ in if t1' = y1
+ then u1
+ else if appear_var_term y1 t1'
+ then raise Up_error
+ else let u1' =
+ List.map (fun (x,t) -> (x,subst_term s1 t1' t)) u1
+ in up ((y1,t1')::u1') uu2
+ | [] -> u1
+ | _ -> failwith "unif__up: impossible case"
+
+(* $Id$ *)
diff --git a/contrib/linear/unif.mli b/contrib/linear/unif.mli
new file mode 100755
index 0000000000..61a29ee8be
--- /dev/null
+++ b/contrib/linear/unif.mli
@@ -0,0 +1,27 @@
+(***********************************************************************)
+(* v * The Coq Proof Assistant / The Coq Development Team *)
+(* <O___,, * INRIA-Rocquencourt & LRI-CNRS-Orsay *)
+(* \VV/ *************************************************************)
+(* // * This file is distributed under the terms of the *)
+(* * GNU Lesser General Public License Version 2.1 *)
+(***********************************************************************)
+
+(*i $Id$ i*)
+
+open General
+open Dpctypes
+
+exception Not_unifiable
+
+val unif_atoms : atom_id * term list -> atom_id * term list
+ -> (term * term) list
+val unif_terms : term -> term -> (term * term) list
+
+val assoc_unif : 'a -> ('a * 'a) list -> 'a
+val apply_unif : (term * term) list -> term -> term
+val appear_var_term : term -> term -> bool
+
+exception Up_error
+
+val up : (term * term) list -> (term * term) list -> (term * term) list
+