(* Coq printing functions for general clauses.
   Copyright (C) 2003, 2008 Jean Goubault-Larrecq and LSV, CNRS UMR 8643 & ENS Cachan.

   This file is part of h1.

   h1 is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2, or (at your option)
   any later version.

   h1 is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with h1; see the file COPYING.  If not, write to
   the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*)

open "coq_gclause_h";
open "coq_term_h";
open "coq_fun_h";
open "coq_kw_h";
open "sort_h";

fun coq_print_gvars (ver, f as |[put, ...]|, varname, varsort, term_type) =
    let val |[forall_prolog, forall_midlog, var_delim, ...]| =
	    coq_keywords ver
    in
	fn vars =>
	   if empty vars
	       then ()
	   else let val delimr = ref forall_prolog
		in
		    iterate
		      (put (!delimr);
		       delimr := var_delim;
		       put (varname x))
		    | x in list varsort vars
		    end;
		    put ":";
		    put term_type;
		    put forall_midlog
		end
    end;

fun coq_print_gclause_vars (ver, f, varname, varsort, term_type) =
    let val cpv = coq_print_gvars (ver, f, varname, varsort, term_type)
    in
	fn c =>
	   let val vars = gclause_vars c
	   in
	       cpv vars
	   end
    end;

fun coq_print_gclause_neg (f_etc as (_, |[put, ...]|, ...)) =
    let val patom = coq_print_atom f_etc
    in
	fn (GCLAUSE (neg, _)) =>
	   (iterate
	      (patom a; put " -> ")
	    | a in list neg
	    end)
    end;

fun coq_print_gclause_pos (f_etc as (_, |[put, ...]|, ...)) =
    let val patom = coq_print_atom f_etc
	fun pgpos nil = put "False"
	  | pgpos [a] = patom a
	  | pgpos [a,a'] = (patom a; put " \\/ "; patom a')
	  | pgpos (a::l) = (patom a; put " \\/ "; pgpos l)
    in
	fn (GCLAUSE (_, pos)) => pgpos pos
    end;

fun coq_print_gclause_lits f_etc =
    let val pgneg = coq_print_gclause_neg f_etc
	val pgpos = coq_print_gclause_pos f_etc
    in
	fn c => (pgneg c; pgpos c)
    end;

fun coq_print_gclause (ver, f as |[put, ...]|,
		       fun_prefix, state_prefix, varname, varsort, term_type) =
    let val pvars = coq_print_gclause_vars (ver, f, varname, varsort, term_type)
	val plits = coq_print_gclause_lits (ver, f, fun_prefix, state_prefix, varname, term_type)
    in
	fn c => (pvars c; plits c)
    end;
