content: package at.ac.tuwien.kr.alpha.commons.programs;
  
  import at.ac.tuwien.kr.alpha.api.programs.InlineDirectives;
  import at.ac.tuwien.kr.alpha.api.programs.atoms.Atom;
  import at.ac.tuwien.kr.alpha.api.programs.rules.Rule;
  import at.ac.tuwien.kr.alpha.api.programs.rules.heads.Head;
  import at.ac.tuwien.kr.alpha.commons.util.Util;
  
  import java.util.Collections;
  import java.util.List;
  
  /**
   * The parent type for all kinds of programs. Defines a program's basic structure (facts + rules + inlineDirectives)
   *
   * @param <R> the type of rule a program permits. This needs to be determined by implementations based on which syntax constructs an
   *            implementation permits
   *            Copyright (c) 2019, the Alpha Team.
   */
  public abstract class AbstractProgram<R extends Rule<? extends Head>> {
  
  	private final List<R> rules;
  	private final List<Atom> facts;
  	private final InlineDirectives inlineDirectives;
  
  	public AbstractProgram(List<R> rules, List<Atom> facts, InlineDirectives inlineDirectives) {
  		this.rules = rules;
  		this.facts = facts;
  		this.inlineDirectives = inlineDirectives;
  	}
  
  	public List<R> getRules() {
  		return Collections.unmodifiableList(rules);
  	}
  
  	public List<Atom> getFacts() {
  		return Collections.unmodifiableList(facts);
  	}
  
  	public InlineDirectives getInlineDirectives() {
  		return inlineDirectives;
  	}
  
  
  	@Override
  	public String toString() {
  		final String ls = System.lineSeparator();
  		final String factString = facts.isEmpty() ? "" : Util.join("", facts, "." + ls, "." + ls);
  		final String ruleString = rules.isEmpty() ? "" : Util.join("", rules, ls, ls);
  		return factString + ruleString;
  	}
  
  }
  