public void requireSanity(State s) {
		boolean sane = true;
		
		if (s.players().length != players.length) {
			System.err.println("inconsistent belief: number of players changed");
			sane = false;
		}
		
		if (!s.deck.containsAll(known_deck_cards)) {
			CardBag surplus = known_deck_cards.clone();
			surplus.removeAll(s.deck);
			System.err.println("inconsistent belief: known_deck_cards "+known_deck_cards+" contains cards "+surplus+" that are not in the deck "+s.deck);
			sane = false;
		}
		for (int i = 0; i < players.length; i++) {
			if (!s.playerState(i).hand.containsAll(players[i].known_cards)) {
				System.err.println("inconsistent belief: for player "+s.playerState(i).name+", known_cards "+players[i].known_cards+" contains cards that are not in the hand "+s.playerState(i).hand);
				sane = false;
			}
		}

		int total_card_count = 0;
		total_card_count = cards_of_unknown_location.size();
		total_card_count += known_deck_cards.size();
		total_card_count += s.open_deck.size();
		total_card_count += s.discarded.size();
		for (int i = 0; i < players.length; i++)
			total_card_count += players[i].known_cards.size();
		if (total_card_count != State.INITIAL_DECK.size()) {
			System.err.println("inconsistent belief: "+total_card_count+" cards in the game, should be "+State.INITIAL_DECK.size());
			sane = false;
		}

		if (!sane) {
			System.err.println("events that led to this belief (most recent event last):");
			for (Event e: events)
				System.err.println("  "+e);
			throw new RuntimeException("inconsistent belief");
		}
	}