Regular search spaces as a foundation of logic programming