// predicate.h -- declarations for predicate data type for lparse
// Copyright (C) 1999-2000 Tommi Syrjänen <Tommi.Syrjanen@hut.fi>
//  
// This program 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 of the License, or
// (at your option) any later version.
//  
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//  

#ifndef PREDICATE_H
#define PREDICATE_H

#include "../config.h"
#ifndef GLOBAL_H
#include "global.h"
#endif
#ifndef LIST_H
#include "list.h"
#endif
#ifndef LITERAL_H
#include "literal.h"
#endif
#ifndef RULE_H
#include "rule.h"
#endif
#ifndef INSTANCE_H
#include "instance.h"
#endif
#ifndef GRAPH_H
#include "graph.h"
#endif

class Predicate
{
public:
  Predicate();
  ~Predicate();

  void AddRule(Rule *, int cmp = 1);
  void AddSpecialRule(Rule *, int cmp = 1);
  void AddWeight(Weight *nw, Literal *lt, int global);
  void AddInstance(Instance *inst);
  void CreateIndex(int index);
  void Emit();
  void PrintRules();
  
  int Arity() { return arity; }
  int HasSpecial() { return special; }
  void SetArity(int ar);
  void SetPred(long p) { pred = p; }
  long Pred() { return pred; }
  char *Name() { return name; }
  void SetName(char *nm) { name = nm; }
  DomainType Status() { return status; }
  void SetStatus(DomainType r) { status = r; }
  long Size();
  void CalculateDomain();
  
  RestrictType CheckRestrict(int print);
  static RestrictType CheckAllRestricts();
  static void EmitAll();
  static void PrintAllRules();
  static long MakeComplement(long, char *, int);
  static long DefinePredicate(char *, int, long);
  static long DefineSystemPredicate(DomainType tp = DM_INTERNAL);
  static long ConstructDummy();
  
  // initialize a complementary predicate to allow regular model
  // semantics to work 
  static void DefineComplement(long pred);

  static void EmitComplements();

  // tries to find predicates without any rules for them 
  static void CheckUnsatisfiable();

  int NeedsToBePrinted();

  static long decode_atom(char *st);
  
  Index **indices;
  InstanceSet *atoms;
  InstanceSet *emitted;
  unsigned long existing_indexes;
  long complement;
  int arity;
  int follows : 1;
  int special : 1;
  int hidden : 1;
  int shown : 1;
  int external_atom : 1;
  int depends_on_external_atoms : 1;
  int has_rule : 1; // true if predicate occurs as a head
  int is_warned : 1; // have we warned about mismatches of this
  		     // predicate
  WeightNode *predicate_weight_list;
  WeightNode *weight_list;

  long first_line; // line of user code where the predicate occurs
		   //first
  
private:
  RuleList rules;
  RuleList special_rules;

  InstanceIterator *it;
  char *name;
  long pred;

  DomainType status;
};
#endif
